Embedded Accounting for SaaS
What it actually takes to put Swedish bookkeeping inside your SaaS product today: scoped API keys per company, 123 REST endpoints, OAuth 2.1 for agent access, and an AGPL core you can self-host. Also the honest part — there is no self-serve tenant provisioning API yet, so onboarding is a conversation, not a POST request.
TL;DRWhat it actually takes to put Swedish bookkeeping inside your SaaS product today: scoped API keys per company, 123 REST endpoints, OAuth 2.1 for agent access, and an AGPL core you can self-host. Also the honest part — there is no self-serve tenant provisioning API yet, so onboarding is a conversation, not a POST request.
If your SaaS serves Swedish small businesses or freelancers, accounting is the highest-stickiness feature you can add. Customers don't churn out of the system holding their verifikat.
This article is the developer-side view of what that integration looks like against the product as it exists today — including the part that isn't built yet.
What exists today
Three things you can build on right now:
- A REST API with 123 documented endpoints, OpenAPI 3.1, at
https://app.accounted.se/api/v1. Every endpoint returns structured errors with a recovery hint. - Scoped API keys. Keys are minted per company at
/settings/apiand carry explicit capability scopes. 118 of 123 endpoints are idempotent; 55 support dry-run. - An MCP server with 130+ tools over OAuth 2.1, if you want your customers' books reachable by an agent rather than only by your backend.
The core is AGPL-3.0 on GitHub, so you can also read exactly what you're integrating against, or self-host it.
What does not exist yet
Being direct about this, because it's the thing that decides whether embedded accounting is viable for you this quarter:
There is no tenant provisioning API. /api/v1/companies is GET-only. It lists the companies a key already has access to. It does not create them.
Companies are created through the web onboarding flow, which involves BankID identification and Skatteverket authorisation — both of which are legally attached to a human, not to your platform. So the current shape is:
- Your customer creates their company in accounted (once, via the web flow).
- They mint an API key, or authorise your platform over OAuth 2.1.
- Your product then operates their books through that credential.
That's a real onboarding seam. It's fine for platforms with a few hundred high-value customers and awkward for a self-serve product with thousands of signups. If you need programmatic provisioning, say so — it's the most-requested embedded gap and it's tracked, not shipped.
The integration shape
1. Discover the companies a key can reach
curl https://app.accounted.se/api/v1/companies \
-H "Authorization: Bearer gnubok_sk_live_..."
Returns the companies that key is authorised for, with their org numbers and fiscal-year configuration.
2. Operate on one company's books
Every resource is nested under a company ID. Nothing is ambiguous about which ledger you're writing to:
curl https://app.accounted.se/api/v1/companies/{companyId}/transactions \
-H "Authorization: Bearer gnubok_sk_live_..."
Reports, invoices, suppliers, journal entries, employees, and SIE export all follow the same /api/v1/companies/{companyId}/... shape.
3. React to changes without polling
24 webhook event types are available — invoice.paid, journal_entry.committed, period.locked, transaction.categorized, and so on. Subscribe with a key holding webhooks:manage, and use /api/v1/webhook-deliveries to inspect and retry deliveries.
If you'd rather poll, the events:read scope exposes the same event log directly.
Scopes are the actual security model
There's no partner-level credential that reaches across your whole customer base. Access is granted per company, per capability. The scopes you'll reach for most:
| Scope | What it unlocks |
|---|---|
transactions:read | List transactions, category suggestions |
transactions:write | Categorise, match against invoices, receipt matching |
invoices:read/write | Customer ledger, create, send, mark paid, credit |
reports:read | Trial balance, general ledger, VAT, KPI, SIE export |
events:read | Poll the event log as a webhook fallback |
webhooks:manage | Create and manage webhook subscriptions |
Keys with no explicit scopes fall back to read-only. OAuth-issued keys default to read-only too: write and approval scopes must be requested by the client and ticked by the user on the consent screen.
One deliberate constraint worth knowing before you design around it: a single key cannot both stage a write and approve it. Staging scopes and pending_operations:approve on the same credential is rejected, because that would let an automated agent post to the books with no human in the loop.
Building the UI
You build it. There is no embeddable React component library — that's a thing I've seen people assume, so: it doesn't exist.
What you get is the API, the OpenAPI spec, and llms.txt / llms-full.txt if you want to point a coding agent at the surface. What you build on top — the categorisation flow, the reports view, the invoice form — is yours, in your design system, on your domain.
For a platform with a competent frontend team, a usable accounting surface covering categorisation, invoices, and the three core reports is a multi-week project, not a multi-quarter one. The compliance-heavy parts — VAT rules, period locking, SIE, BAS validation — are the parts you're not building.
Compliance: who owns what
The books belong to your customer
Your end customer is the obligated party under Bokföringslagen and the data controller under GDPR. Your platform is a processor; accounted is a sub-processor. Standard chain, standard DPA.
Practically: they can export complete SIE4 at any time, and you cannot delete their books unilaterally. Design your offboarding assuming they'll leave with everything.
The audit log is per company
Every state change is an event attributed to a user and a session. A revisor auditing your customer's books reads it directly. Agent activity is traceable to the credential that produced it.
Filings stay between your customer and Skatteverket
Each company authorises accounted as its ombud, or files manually. Your product can surface "file your VAT return" as a feature, but the filing is signed with BankID by a human. You can't file on their behalf from your backend.
Three questions before you commit
-
How Swedish is your customer base? This works for Swedish-registered companies. If most of your customers are international, this is the wrong integration — the whole value is doing one jurisdiction properly.
-
Can you live with the onboarding seam? Until provisioning is programmatic, each customer does a one-time setup in accounted. If that kills your activation funnel, wait for it or talk to us about the timeline.
-
Do you have a monetisation story? Embedded accounting given away free tends to be treated as a low-value feature. Customers value it partly because it costs money to operate.
What to do next
- Read The Accounting API for the AI Era for the broader positioning.
- Read Building on an Open Source Swedish Ledger for self-hosting and the validation core.
- Get a sandbox key and call
/api/v1/companiesagainstgnubok_sk_test_*before you plan anything. - Contact us via /byraer for commercial licensing. Embedded pricing is set after a review of your volume and use case — there's no published rate card.
Embedded accounting is underrated as a growth lever for Swedish vertical SaaS. It's also further from turnkey than the category's marketing usually admits. Both things are true, and you should plan against the second one.
Frequently asked
- Why would a SaaS want to embed accounting?
- Stickiness and revenue. Customers don't leave when their books live inside your product, and a per-customer accounting subscription stacks on top of your existing price. For verticalised SaaS in e-commerce, freelance platforms, or agency tooling, it's often the obvious upsell.
- Is this Plaid for accounting?
- Closer to a ledger you rent than a data aggregator. Plaid is read-only account aggregation; accounted is a full Swedish double-entry ledger with validation, VAT rules, and Skatteverket filings. You're not reading financial data, you're producing it.
- Can I provision a new customer's books via API?
- Not yet. `/api/v1/companies` is read-only — it lists the companies an API key can reach. Companies are created through the web onboarding flow, which needs BankID. Programmatic provisioning is the main gap for embedded use cases; talk to us if it blocks you.
- How is one customer's data isolated from another's?
- Every company is a separate ledger with its own accounts, fiscal periods, and audit log. API keys are scoped per company and per capability (`transactions:read`, `invoices:write`, and so on). A key issued for one company cannot read another's data.
- What's the commercial model?
- Set after a review of your volume and use case — there's no published embedded price list. The core is AGPL-3.0, so embedding it in a proprietary product needs a commercial licence. Start at /byraer.
Last updated: July 26, 2026