Menu
Cookbooks
API reference
- Overview
- Companies
- Customers
- Invoices
- Articles
- Suppliers
- Supplier invoices
- Supplier payment files
- Expense claims
- Transactions
- Reconciliation
- Bank accounts
- Journal entries
- Voucher gap explanations
- Fiscal periods
- Accounts
- Fixed assets
- Documents
- Inbox items
- Dimensions
- Employees
- Salary runs
- Reports
- Imports
- Compliance check
- Skatteverket
- Peppol
- Webhooks
- Operations
- Health
Reports
Reports and filing: trial balance, P&L, balance sheet, GL, VAT with eSKD and the settlement, INK2 and NE-bilaga with SRU files, periodisk sammanställning, cash flow, KPI, behandlingshistorik, bokslutsbilagor, the audit trail, SIE export and more.
Endpoints
GET/api/v1/companies/:companyId/audit-trail: The audit log: every trigger-recorded change to the books and their settings, newest first.GET/api/v1/companies/:companyId/reports/ar-ledger: AR ledger: unpaid customer invoices with aging.GET/api/v1/companies/:companyId/reports/avgifter-basis: Annual arbetsgivaravgifter basis per employee.GET/api/v1/companies/:companyId/reports/balance-sheet: Balance sheet (balansräkning) for a fiscal period or as of a custom date.GET/api/v1/companies/:companyId/reports/balance-sheet/pdf: Balance sheet (balansräkning) as a PDF.GET/api/v1/companies/:companyId/reports/behandlingshistorik: Behandlingshistorik (BFL 5 kap. 11 §): who changed what in the books, and when, for a räkenskapsår.GET/api/v1/companies/:companyId/reports/bokslutsbilagor: Bokslutsbilagor: every balance account at the balansdag with its specification, sign-off and underlag.GET/api/v1/companies/:companyId/reports/continuity-check: IB/UB continuity check: opening balances match prior closing.GET/api/v1/companies/:companyId/reports/dimension-pnl: Resultat per projekt or kostnadsställe: the income statement with one column per dimension value.GET/api/v1/companies/:companyId/reports/general-ledger: General ledger (huvudbok) for a fiscal period.GET/api/v1/companies/:companyId/reports/income-statement: Income statement (resultatrapport) for a fiscal period or a custom date range.GET/api/v1/companies/:companyId/reports/income-statement/pdf: Income statement (resultaträkning) as a PDF.GET/api/v1/companies/:companyId/reports/ink2: INK2 inkomstdeklaration (aktiebolag): INK2, INK2R and INK2S fields for a räkenskapsår.GET/api/v1/companies/:companyId/reports/ink2/sru: INK2 SRU files (INFO.SRU + BLANKETTER.SRU) as a zip, for upload at skatteverket.se.GET/api/v1/companies/:companyId/reports/journal-register: Journal register (verifikationsregister) for a fiscal period.GET/api/v1/companies/:companyId/reports/kassaflodesanalys: Kassaflödesanalys (cash flow statement, indirect method) for a räkenskapsår.GET/api/v1/companies/:companyId/reports/kpi: Business KPIs (nyckeltal) for a fiscal period, as the dashboard shows them.GET/api/v1/companies/:companyId/reports/monthly-breakdown: Income statement broken down by month for a fiscal period.GET/api/v1/companies/:companyId/reports/ne-bilaga: NE-bilaga (enskild firma): rutor R1-R11 for a räkenskapsår.GET/api/v1/companies/:companyId/reports/ne-bilaga/sru: NE-bilaga SRU files (INFO.SRU + BLANKETTER.SRU) as a zip, for upload at skatteverket.se.GET/api/v1/companies/:companyId/reports/periodisk-sammanstallning: Periodisk sammanställning (EU sales list): per-customer EU sales of goods, services and triangulation.GET/api/v1/companies/:companyId/reports/periodisk-sammanstallning/csv: Periodisk sammanställning as the SKV 574008 CSV file, for upload at skatteverket.se.GET/api/v1/companies/:companyId/reports/salary-journal: Salary journal (lönejournal) for a year and optional month range.GET/api/v1/companies/:companyId/reports/sie-export: SIE4 export (.se file) for a fiscal period.GET/api/v1/companies/:companyId/reports/supplier-ledger: Supplier ledger: unpaid supplier invoices with aging.GET/api/v1/companies/:companyId/reports/trial-balance: Trial balance (huvudboksrapport) for a fiscal period.GET/api/v1/companies/:companyId/reports/vacation-liability: Vacation liability (semesterlöneskuld) per employee at year-end.GET/api/v1/companies/:companyId/reports/vat-declaration: Swedish VAT declaration (momsdeklaration) for a period.GET/api/v1/companies/:companyId/reports/vat-declaration/eskd: Momsdeklaration as an eSKD XML file, for "Deklarera via fil" at skatteverket.se.GET/api/v1/companies/:companyId/reports/vat-declaration/filings: List the calendar VAT periods the company has recorded as filed.GET/api/v1/companies/:companyId/reports/vat-declaration/settlement-proposal: The proposed momsredovisning verifikat for a VAT period: clear 26xx to 2650 or 1650.POST/api/v1/companies/:companyId/reports/vat-declaration/filings: Record that a VAT period was filed outside the Skatteverket connection.POST/api/v1/companies/:companyId/vat/settlement: Book the momsredovisning verifikat for a VAT period, exactly as the proposal gives it.DELETE/api/v1/companies/:companyId/reports/vat-declaration/filings: Undo a manual "filed" mark on a VAT period.
GET /api/v1/companies/:companyId/audit-trail
audit-trail.list · scope reports:read
The audit log: every trigger-recorded change to the books and their settings, newest first.
Rows the database triggers write on every insert, update and delete of bookkeeping tables (verifikationer and their lines, kontoplan, fiscal periods, settings, suppliers, imports, ...) and on commits, reversals, corrections and locks: action, table, record id, actor (user, API key, MCP connection, cron), description and the old and new row state. Filter by action, table_name, record_id and a created_at window. Cursor pagination: pass next_cursor back as cursor; next_cursor is null on the last page. Read-only: nothing can write the log except the triggers.
Use when: Tracing exactly how one record changed (record_id), or exporting the raw log for an auditor.
Don't use for: The readable processing history for a räkenskapsår (GET /reports/behandlingshistorik).
Pitfalls
- old_state / new_state are whole row snapshots and can hold personal data (a sole trader's org number is the owner's personnummer, supplier bank details): only an owner or admin of the company receives them (snapshots_included true). Other callers get old_state/new_state null and changed_fields, the column names that changed.
- from_date / to_date compare against the created_at timestamp: to_date=2026-01-31 stops at 2026-01-31T00:00:00Z. Pass the next day to include all of the 31st.
- The page is in data.entries with data.next_cursor; a cursor that no longer decodes starts from the first page.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
action | "INSERT" | "UPDATE" | "DELETE" | "COMMIT" | "REVERSE" | "CORRECT" | "LOCK_PERIOD" | "CLOSE_PERIOD" | "DOCUMENT_DELETE_BLOCKED" | "RETENTION_BLOCK" | "SECURITY_EVENT" | "INTEGRITY_FAILURE" | "COMMITTED_AT_OVERRIDE" | no | Only this action (INSERT, UPDATE, DELETE, COMMIT, REVERSE, CORRECT, LOCK_PERIOD, CLOSE_PERIOD, ...). |
table_name | string | no | Only rows about this table, e.g. journal_entries. |
record_id | string | no | Only rows about this record id. |
from_date | string | no | created_at on or after this date (YYYY-MM-DD). |
to_date | string | no | created_at on or before this date's midnight (YYYY-MM-DD). |
cursor | string | no | next_cursor from the previous page. Omit for the first page. |
limit | number | no | Page size, 1-200 (default 50). |
Response fields
| Name | Type | Description |
|---|---|---|
entries | object[] | |
next_cursor | string | null | |
snapshots_included | boolean | false unless the caller is an owner or admin of the company: old_state/new_state are then null. |
Example request
{
"table_name": "journal_entries",
"limit": 1
}
Example response
{
"data": {
"entries": [
{
"id": "0d5e…",
"action": "COMMIT",
"table_name": "journal_entries",
"record_id": "9a0b…",
"actor_type": "api_key",
"actor_label": "Integration",
"description": "Verifikation A12 bokförd",
"old_state": null,
"new_state": {
"status": "posted"
},
"created_at": "2026-03-02T09:14:00Z"
}
],
"next_cursor": "eyJ0cyI6…"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/ar-ledger
reports.ar-ledger · scope reports:read
AR ledger: unpaid customer invoices with aging.
Returns the customer-receivable ledger as of as_of_date (defaults to today). Each customer entry includes outstanding invoices grouped into aging buckets (0-30, 31-60, 61-90, 90+ days). Reconciles against BAS 1510.
Use when: Cash collection dashboards, dunning workflows, end-of-period reconciliation against the 1510 trial-balance figure.
Don't use for: Listing all invoices regardless of status (use /invoices). Sending dunning emails (the v1 surface does not yet expose dunning).
Pitfalls
as_of_dateis optional; formatYYYY-MM-DD. Defaults to today (UTC).- Only invoices in
sent/overdue/partially_paidstatus appear. Drafts and credited invoices are excluded. - The ledger is built from the invoice register only.
data.register_coverage({ covers_from, has_pre_register_invoices }) discloses when posted AR verifikat predate the register's earliest invoice (migrated or backfilled invoice history): those receivables are NOT in this ledger. When has_pre_register_invoices is true, treat periods before covers_from as unanswered here and query journal entries on 1510/1513 instead.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
as_of_date | string | no | YYYY-MM-DD, a real calendar date between 2000 and next year. Default: today (UTC). |
Example response
{
"data": {
"as_of_date": "2026-05-31",
"customers": [],
"totals": {}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/avgifter-basis
reports.avgifter-basis · scope payroll:read
Annual arbetsgivaravgifter basis per employee.
Returns the annual avgifter basis per employee for year, summed across booked salary runs. Each row shows the basis, applied rate, and computed avgifter amount: useful for reconciling against monthly AGI filings (HU sum across the year).
Use when: Annual reconciliation between the AGI declarations and the bookkeeping (BAS 7510). Year-end audit prep.
Don't use for: Real-time AGI generation (POST /salary-runs/{id}/generate-agi). Per-run breakdown (use /reports/salary-journal).
Pitfalls
yearis required.- Only
bookedruns are included.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
year | number | yes | Year, 2020-2100. Required. |
Example response
{
"data": {
"year": 2026,
"employees": [],
"totals": {}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/balance-sheet
reports.balance-sheet · scope reports:read
Balance sheet (balansräkning) for a fiscal period or as of a custom date.
Returns assets / liabilities / equity grouped into BAS sections, with the period's opening and closing balances. Optional as_of (alias for to_date, YYYY-MM-DD inside the fiscal period) returns the balance position at that date, e.g. the latest month-end for bank reporting. Sums match the income statement for the same period; the closing equity flows into next period's opening balance.
Use when: You need the company's balance position at period end or at a custom date: typically management reporting, year-end review, or the K2/K3 årsredovisning uppställningsform.
Don't use for: Per-account drill-down (use /reports/general-ledger). Net result for the period (use /reports/income-statement).
Pitfalls
period_idis required;as_of(alias:to_date, pass at most one) is optional and must lie within that fiscal period.from_dateis not accepted: a balance sheet is a cumulative position, not a flow over a window.- Unknown query parameters are rejected with VALIDATION_ERROR, not silently ignored.
- Balance sheet equity includes the period's computed result: recalculation happens on every call, so a freshly-posted entry is reflected immediately (no caching).
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
to_date | string | no | YYYY-MM-DD inside the fiscal period: the position as of this date. Default: the period end. |
as_of | string | no | Alias for to_date. Pass one or the other, not both. |
Example response
{
"data": {
"period": {
"start": "2026-01-01",
"end": "2026-12-31"
},
"sections": [],
"totals": {}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/balance-sheet/pdf
reports.balance-sheet.pdf · scope reports:read
Balance sheet (balansräkning) as a PDF.
Renders the balansräkning as application/pdf, byte-equivalent to the dashboard export. Optional as_of (alias for to_date, YYYY-MM-DD inside the fiscal period) returns the balance position at that date, e.g. the latest month-end for bank reporting. Refuses to render when tillgångar and eget kapital + skulder differ by a full krona or more.
Use when: You need a presentable PDF of the balance position at period end or a custom date: bank requests, board packs, or sharing outside Accounted.
Don't use for: Machine-readable figures (use the JSON endpoint without /pdf). The formal K2/K3 årsredovisning document (use the year-end flow).
Pitfalls
period_idis required;as_of(alias:to_date, pass at most one) is optional and must lie within that fiscal period.from_dateis not accepted: a balance sheet is a cumulative position, not a flow over a window.- Unknown query parameters are rejected with VALIDATION_ERROR, not silently ignored.
- An unbalanced balansräkning (>= 1 kr difference) returns REPORT_GENERATION_FAILED instead of a PDF: fix the imbalance first.
- The PDF is marked "utkast": it is a working report, not a fastställd årsredovisning.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
to_date | string | no | YYYY-MM-DD inside the fiscal period: the position as of this date. Default: the period end. |
as_of | string | no | Alias for to_date. Pass one or the other, not both. |
Example response
{
"_note": "Returns application/pdf binary stream."
}
GET /api/v1/companies/:companyId/reports/behandlingshistorik
reports.behandlingshistorik · scope reports:read
Behandlingshistorik (BFL 5 kap. 11 §): who changed what in the books, and when, for a räkenskapsår.
The processing history the system documentation must include (BFNAR 2013:2 p. 9.16): verifikationer posted, corrected and reversed, chart of accounts and settings changes, period locks and closings, imports, access changes and program versions, each with time, actor (user, API key, MCP connection, cron) and detail lines. Filter by from_date / to_date inside the period and by one category, as the dashboard report. For an enskild firma the owner's personnummer is masked. Read-only.
Use when: An auditor or Skatteverket asks how the books were processed, or you need to know who posted or changed something.
Don't use for: The raw row-level audit log (GET /audit-trail) or the verifikationslista (GET /reports/journal-register).
Pitfalls
- from_date and to_date must lie inside the fiscal period (400 VALIDATION_ERROR otherwise).
- Bursts of identical changes are collapsed into one event with count > 1.
- The statutory PDF, CSV and Excel exports are in the dashboard; this is the same report as JSON.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
from_date | string | no | YYYY-MM-DD inside the period. Omit for the whole period. |
to_date | string | no | YYYY-MM-DD inside the period, not before from_date. |
category | "verifikation" | "kontoplan" | "installningar" | "period" | "import" | "atkomst" | "arkiv" | "ovrigt" | no | Only events of this category. |
Response fields
| Name | Type |
|---|---|
company | object |
period | object |
range | object |
mode | "fiscal_year" | "date_range" |
generated_at | string |
app_version | string | null |
total_events | number |
by_category | object |
events | object[] |
Example request
{
"period_id": "7c2b…",
"category": "verifikation"
}
Example response
{
"data": {
"company": {
"name": "Testbolaget AB",
"org_number": "5566778899"
},
"period": {
"fiscal_period_id": "7c2b…",
"name": "2026",
"start": "2026-01-01",
"end": "2026-12-31"
},
"range": {
"from": "2026-01-01",
"to": "2026-12-31"
},
"mode": "fiscal_year",
"total_events": 1,
"events": [
{
"event_id": "entry:9a0b…",
"occurred_at": "2026-03-02T09:14:00Z",
"category": "verifikation",
"code": "journal_entry.committed",
"event": "Verifikation bokförd",
"object": "A12",
"actor": {
"type": "api_key",
"user_id": null,
"label": "Integration"
},
"details": [],
"source": "journal_entries",
"count": 1
}
]
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/bokslutsbilagor
reports.bokslutsbilagor · scope reports:read
Bokslutsbilagor: every balance account at the balansdag with its specification, sign-off and underlag.
The bokslutsbilagor pärm for one räkenskapsår: each balance account as of the balansdag with its balance, specification or stated balance, who signed it off and when, the attached underlag files with their SHA-256, and the year-end checklist with its state. For an enskild firma the owner's personnummer is masked. Read-only.
Use when: Checking which balance accounts are specified and signed off before bokslut, or handing the specification to an auditor.
Don't use for: The balance sheet figures alone (GET /reports/balance-sheet) or the account reconciliation work itself.
Pitfalls
- summary.unsigned counts accounts nobody has signed off; signed_other_date were signed against another date than the balansdag.
- The PDF of the pärm is in the dashboard; this is the same report as JSON.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
Response fields
| Name | Type |
|---|---|
company | object |
period | object |
generated_at | string |
app_version | string | null |
checklist | object |
accounts | object[] |
summary | object |
Example request
{
"period_id": "7c2b…"
}
Example response
{
"data": {
"company": {
"name": "Testbolaget AB",
"org_number": "5566778899"
},
"period": {
"fiscal_period_id": "7c2b…",
"name": "2025",
"start": "2025-01-01",
"end": "2025-12-31"
},
"summary": {
"accounts": 14,
"signed_on_balansdag": 12,
"signed_other_date": 0,
"unsigned": 2,
"attachments": 9
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/continuity-check
reports.continuity-check · scope reports:read
IB/UB continuity check: opening balances match prior closing.
Validates that the target period's opening balances (IB) equal the prior period's closing balances (UB). The requirement derives from BFL 5 kap (löpande bokföring), BFNAR 2013:2 (systemdokumentation/behandlingshistorik), and the SIE4 spec's core invariant that #IB(year N) must equal #UB(year N-1). Returns per-account discrepancies so an operator can rectify them before period close.
Use when: Before locking or closing a period, or as part of an automated year-end readiness gate. Any discrepancy is a hard data-integrity issue.
Don't use for: Computing balances (use /reports/balance-sheet or /reports/trial-balance). Closing the period (POST /fiscal-periods/{id}/close).
Pitfalls
period_idis required.- A non-zero discrepancy means IB ≠ prior UB and indicates the opening-balance entry was edited or the prior period was changed after close. Investigate before posting any new entries.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
Example response
{
"data": {
"is_continuous": true,
"discrepancies": []
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/dimension-pnl
reports.dimension-pnl · scope reports:read
Resultat per projekt or kostnadsställe: the income statement with one column per dimension value.
A value-as-column P&L matrix over one SIE dimension (dim_no 6 projekt by default, 1 kostnadsställe, or a custom dimension): each result account's amount per dimension value, an "(Utan dimension)" column for untagged amounts, and a Totalt column that equals the resultatrapport. Cumulative from the period start to to_date (default the period end). Read-only.
Use when: Following up profitability per project or cost centre.
Don't use for: One value only (GET /reports/income-statement with a dimension filter) or balance accounts (dimensions are P&L-side).
Pitfalls
- No from_date: the matrix uses closing-balance semantics so its Totalt reconciles with the resultatrapport.
- Amounts booked without a tag on the dimension land in "(Utan dimension)", not spread over the values.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
dim_no | string | no | SIE dimension number. Default "6" (projekt). |
to_date | string | no | YYYY-MM-DD inside the period. Default: the period end. |
Response fields
| Name | Type |
|---|---|
dimension | object |
columns | object[] |
groups | object[] |
net_per_column | number[] |
net_total | number |
period | object |
Example request
{
"period_id": "7c2b…",
"dim_no": "6"
}
Example response
{
"data": {
"dimension": {
"sie_dim_no": "6",
"name": "Projekt"
},
"columns": [
{
"code": "P001",
"name": "Projekt Alfa"
}
],
"net_total": 184200,
"period": {
"start": "2026-01-01",
"end": "2026-12-31"
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/general-ledger
reports.general-ledger · scope reports:read
General ledger (huvudbok) for a fiscal period.
Returns every posted journal line in the period grouped by account, with opening / running / closing balances. Supports optional account_from and account_to query parameters to limit the report to an account range (e.g. ?account_from=3000&account_to=3999 for revenue-only).
Use when: You're reconciling a specific account or range (bank account drilldown, revenue audit, expense investigation) and need every voucher-line that hit the account.
Don't use for: Period totals only (use /reports/trial-balance). Specific transaction lookup (use /journal-entries/{id}).
Pitfalls
period_idis required.- Account ranges are inclusive on both bounds.
account_from=3000includes 3000;account_to=3999includes 3999. - Lines with
status != 'posted'(drafts, reversed) are excluded.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
account_from | string | no | Lowest account number to include (inclusive), 3-8 digits, e.g. 3000. |
account_to | string | no | Highest account number to include (inclusive), 3-8 digits, e.g. 3999. |
Example response
{
"data": {
"period": {},
"accounts": []
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/income-statement
reports.income-statement · scope reports:read
Income statement (resultatrapport) for a fiscal period or a custom date range.
Returns the period's revenue and expenses grouped by BAS class with subtotals (gross margin, operating result, net result). Optional from_date / to_date (YYYY-MM-DD, inside the fiscal period) narrow the report to a custom range, e.g. January 1 to July 31 for month-end bank reporting. The net result flows into the balance-sheet equity for the same period.
Use when: You need the company's profit/loss for a period or partial period: month-end management reporting, K2/K3 årsredovisning resultaträkning, or feeding KPI dashboards.
Don't use for: Per-account drill (use /reports/general-ledger). VAT figures (use /reports/vat-declaration). Balance position (use /reports/balance-sheet).
Pitfalls
period_idis required;from_date/to_dateare optional and must lie within that fiscal period.- Unknown query parameters are rejected with VALIDATION_ERROR, not silently ignored.
- Net result on the income statement equals the period's equity-line delta on the balance sheet: they're derived from the same posted entries.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
from_date | string | no | YYYY-MM-DD, inside the fiscal period. Omit with to_date for the whole period. |
to_date | string | no | YYYY-MM-DD, inside the fiscal period and not before from_date. |
Example response
{
"data": {
"period": {
"start": "…",
"end": "…"
},
"sections": [],
"grossMargin": 0,
"netResult": 0
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/income-statement/pdf
reports.income-statement.pdf · scope reports:read
Income statement (resultaträkning) as a PDF.
Renders the resultaträkning as application/pdf, byte-equivalent to the dashboard export. Optional from_date / to_date (YYYY-MM-DD, inside the fiscal period) narrow the report to a custom range. The filename carries the effective date range and an "utkast" suffix (the document is a working report, not a signed årsredovisning).
Use when: You need a presentable PDF of the profit/loss for a period or partial period: bank requests, board packs, or sharing outside Accounted.
Don't use for: Machine-readable figures (use the JSON endpoint without /pdf). The formal K2/K3 årsredovisning document (use the year-end flow).
Pitfalls
period_idis required;from_date/to_dateare optional and must lie within that fiscal period.- Unknown query parameters are rejected with VALIDATION_ERROR, not silently ignored.
- The PDF is marked "utkast": it is a working report, not a fastställd årsredovisning.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
from_date | string | no | YYYY-MM-DD, inside the fiscal period. Omit with to_date for the whole period. |
to_date | string | no | YYYY-MM-DD, inside the fiscal period and not before from_date. |
Example response
{
"_note": "Returns application/pdf binary stream."
}
GET /api/v1/companies/:companyId/reports/ink2
reports.ink2 · scope reports:read
INK2 inkomstdeklaration (aktiebolag): INK2, INK2R and INK2S fields for a räkenskapsår.
Computes the aktiebolag income tax return from the books, keyed by SRU field code: ink2 (page 1: 7104 överskott / 7114 underskott), ink2r (räkenskapsschema: balance sheet and income statement, the balance sheet from the closed books and the income statement before the resultatavslut) and ink2s (skattemässiga justeringar, including the adjustments saved in the year-end flow), with the per-code account breakdown, totals and warnings. The SRU files for upload at skatteverket.se are served by GET /reports/ink2/sru; sru_file names that path. Read-only.
Use when: Preparing or checking the aktiebolag income tax return after bokslut, or reconciling INK2R figures against the årsredovisning.
Don't use for: Enskild firma (GET /reports/ne-bilaga), the årsredovisning itself, or submitting to Skatteverket (upload the SRU files at skatteverket.se; nothing is sent from here).
Pitfalls
- Only for aktiebolag: another legal form answers 400 TAX_DECL_INK2_WRONG_LEGAL_FORM.
- Amounts are whole kronor as Skatteverket takes them; codes with no amount are 0.
- Run it after the year-end closing: before bokslut the tax (8910) and bokslutsdispositioner are missing, and warnings say so.
- A period id from another company answers 404 FISCAL_PERIOD_NOT_FOUND.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
Response fields
| Name | Type | Description |
|---|---|---|
fiscalYear | object | |
ink2 | object | |
ink2r | object | |
ink2s | object | |
breakdown | object | |
totals | object | |
companyInfo | object | |
warnings | string[] | |
sru_file | object | Where to fetch INFO.SRU + BLANKETTER.SRU (ISO 8859-1, zipped) for upload at skatteverket.se. |
Example request
{
"period_id": "7c2b…"
}
Example response
{
"data": {
"fiscalYear": {
"fiscal_period_id": "7c2b…",
"name": "2025",
"start": "2025-01-01",
"end": "2025-12-31",
"isClosed": true
},
"ink2": {
"7011": "20250101",
"7012": "20251231",
"7104": 184200,
"7114": 0
},
"ink2r": {
"7251": 250000,
"7410": 1200000
},
"ink2s": {
"7650": 146000,
"7651": 38200,
"7670": 184200
},
"totals": {
"totalAssets": 910000,
"totalEquityLiabilities": 910000,
"operatingResult": 190000,
"aretsResultat": 146000
},
"warnings": [],
"sru_file": {
"download": "/api/v1/companies/…/reports/ink2/sru?period_id=7c2b…",
"content_type": "application/zip",
"files": [
"INFO.SRU",
"BLANKETTER.SRU"
]
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/ink2/sru
reports.ink2.sru · scope reports:read
INK2 SRU files (INFO.SRU + BLANKETTER.SRU) as a zip, for upload at skatteverket.se.
The aktiebolag income tax return as the two SRU files Skatteverket's filöverföring takes, ISO 8859-1 encoded and zipped, byte-identical to the dashboard download. The figures are those of GET /reports/ink2 for the same period. Nothing is sent to Skatteverket: the user uploads the files, reviews and signs there.
Use when: The INK2 figures are reviewed and the files are to be uploaded at skatteverket.se (Filöverföring).
Don't use for: Reading the figures (GET /reports/ink2), or an enskild firma (GET /reports/ne-bilaga/sru).
Pitfalls
- Unzip and upload INFO.SRU and BLANKETTER.SRU under exactly those names; do not re-encode them to UTF-8.
- Only for aktiebolag: another legal form answers 400 TAX_DECL_INK2_WRONG_LEGAL_FORM.
- Refused while an SIE import is unfinished: complete or undo it first.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id. |
Example response
{
"_note": "Returns application/zip as a binary download."
}
GET /api/v1/companies/:companyId/reports/journal-register
reports.journal-register · scope reports:read
Journal register (verifikationsregister) for a fiscal period.
Returns every committed journal entry in the period with its voucher number, date, description, and complete debit/credit line set. The canonical compliance report: what an accountant or Skatteverket audit would pull as proof of every booking.
Use when: You need the BFL-required register of all verifikationer for a period: typically for an audit, year-end review, or feeding an external accountant's tooling.
Don't use for: Per-account drilldown (use /reports/general-ledger). Aggregate totals only (use /reports/trial-balance).
Pitfalls
period_idis required.- Output includes every line of every entry: large periods produce large responses. Consider paginating client-side or filtering by date range via /journal-entries list if you only need a slice.
- Reversed entries appear with status
reversed; the original they reversed also remains.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
Example response
{
"data": {
"period": {},
"entries": []
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/kassaflodesanalys
reports.kassaflodesanalys · scope reports:read
Kassaflödesanalys (cash flow statement, indirect method) for a räkenskapsår.
Derives the cash flow statement from the trial balance: löpande verksamhet (result after financial items, avskrivningar, changes in receivables, inventory and short-term liabilities, tax paid), investeringsverksamhet and finansieringsverksamhet, with a reconciliation of the calculated change against the actual change in cash (1xxx liquid funds). Read-only.
Use when: Preparing the årsredovisning for a K3 company (or a larger K2 one that includes it), or analysing where the year's cash went.
Don't use for: Liquidity forecasts or bank balances (GET /reports/trial-balance for 19xx).
Pitfalls
- reconciliation.is_reconciled false means an account the analysis cannot classify moved; it does not by itself mean the books are wrong.
- A year whose income tax cannot be separated from other taxes answers 422 CASH_FLOW_TAX_ALLOCATION_REQUIRED.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
Response fields
| Name | Type |
|---|---|
fiscal_period_id | string |
period_start | string |
period_end | string |
lopande | object |
investerings | object |
finansierings | object |
total_cash_flow | number |
reconciliation | object |
Example request
{
"period_id": "7c2b…"
}
Example response
{
"data": {
"fiscal_period_id": "7c2b…",
"period_start": "2025-01-01",
"period_end": "2025-12-31",
"lopande": {
"total": 212000
},
"investerings": {
"total": -45000
},
"finansierings": {
"total": -50000
},
"total_cash_flow": 117000,
"reconciliation": {
"is_reconciled": true,
"mismatch_amount": 0
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/kpi
reports.kpi · scope reports:read
Business KPIs (nyckeltal) for a fiscal period, as the dashboard shows them.
Net result, cash position, outstanding and overdue receivables, VAT liability, revenue and expenses, gross margin, expense ratio, average payment days, the monthly trend, the expense composition by BAS class 4-7, the five largest expense accounts and the largest suppliers in SEK. The company's KPI preferences (account overrides for cash and VAT) apply. dim_no + dim_code filter the P&L-side figures to one cost centre or project; balance-side figures stay company-wide. Read-only.
Use when: A dashboard or monthly summary needs the same nyckeltal the Accounted overview shows.
Don't use for: The full income statement or balance sheet (GET /reports/income-statement, /reports/balance-sheet).
Pitfalls
- With a dimension filter, cashPosition, receivables, vatLiability and topSuppliers are still company-wide: do not present them as the dimension's.
- topSuppliersUnconvertedFxCount counts foreign-currency invoices left out of topSuppliers for lack of a SEK amount.
- dim_no and dim_code must be sent together.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
dim_no | string | no | SIE dimension number, e.g. "6" projekt, "1" kostnadsställe. |
dim_code | string | no | The dimension value code, e.g. "P001". Sent with dim_no. |
Response fields
| Name | Type |
|---|---|
netResult | number |
cashPosition | number |
outstandingReceivables | number |
overdueReceivables | number |
vatLiability | number |
totalRevenue | number |
totalExpenses | number |
grossMargin | number | null |
expenseRatio | number | null |
avgPaymentDays | number | null |
periodComplete | boolean |
months | object[] |
period | object |
Example request
{
"period_id": "7c2b…"
}
Example response
{
"data": {
"netResult": 184200,
"cashPosition": 312000,
"outstandingReceivables": 45000,
"overdueReceivables": 5000,
"vatLiability": 18750,
"totalRevenue": 980000,
"totalExpenses": 795800,
"grossMargin": 0.62,
"expenseRatio": 0.81,
"avgPaymentDays": 24,
"periodComplete": false,
"period": {
"start": "2026-01-01",
"end": "2026-12-31"
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/monthly-breakdown
reports.monthly-breakdown · scope reports:read
Income statement broken down by month for a fiscal period.
Returns revenue + expenses + net result per calendar month inside the fiscal period. The sum across all months equals the period's full income-statement totals.
Use when: Building a trend chart, computing rolling KPIs, or producing a månadsrapport for management.
Don't use for: Single-month snapshot only (call /reports/income-statement with a month-sized period). Cash flow analysis (a dedicated cash-flow report is not yet on v1).
Pitfalls
period_idis required.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
Example response
{
"data": {
"period": {},
"months": []
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/ne-bilaga
reports.ne-bilaga · scope reports:read
NE-bilaga (enskild firma): rutor R1-R11 for a räkenskapsår.
Computes the NE-bilaga rutor R1-R11 from the books before the resultatavslut (försäljning, momsfria intäkter, varuinköp, övriga kostnader, lönekostnader, räntor, avskrivningar, årets resultat), with the per-ruta account breakdown and warnings. The owner's personnummer (the enskild firma's org number) is masked in this JSON; the SRU files for upload at skatteverket.se, served by GET /reports/ne-bilaga/sru, carry it in full. Read-only.
Use when: Preparing or checking the enskild firma's NE-bilaga after bokslut.
Don't use for: Aktiebolag (GET /reports/ink2), the egenavgifter / räntefördelning / periodiseringsfond adjustments (MCP gnubok_preview_ef_declaration), or submitting (upload the SRU files at skatteverket.se).
Pitfalls
- Only for enskild firma: another legal form answers 400 TAX_DECL_NE_WRONG_LEGAL_FORM.
- companyInfo.orgNumber is masked (last four digits XXXX): take the full number from the SRU file or the company settings, never from this JSON.
- R11 (årets resultat) is the booked result; the declaration-only adjustments (egenavgifter, räntefördelning, periodiseringsfond, expansionsfond) are not in it.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id, from GET /fiscal-periods. |
Response fields
| Name | Type | Description |
|---|---|---|
fiscalYear | object | |
rutor | object | |
breakdown | object | |
companyInfo | object | |
warnings | string[] | |
sru_file | object | Where to fetch INFO.SRU + BLANKETTER.SRU (ISO 8859-1, zipped) for upload at skatteverket.se. |
Example request
{
"period_id": "7c2b…"
}
Example response
{
"data": {
"fiscalYear": {
"fiscal_period_id": "7c2b…",
"name": "2025",
"start": "2025-01-01",
"end": "2025-12-31",
"isClosed": true
},
"rutor": {
"R1": 480000,
"R2": 0,
"R3": 0,
"R4": 0,
"R5": 120000,
"R6": 95000,
"R7": 0,
"R8": 0,
"R9": 0,
"R10": 12000,
"R11": 253000
},
"companyInfo": {
"companyName": "Anna Svensson Konsult",
"orgNumber": "19800101-XXXX",
"addressLine1": null,
"postalCode": null,
"city": null,
"email": null
},
"warnings": [],
"sru_file": {
"download": "/api/v1/companies/…/reports/ne-bilaga/sru?period_id=7c2b…",
"content_type": "application/zip",
"files": [
"INFO.SRU",
"BLANKETTER.SRU"
]
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/ne-bilaga/sru
reports.ne-bilaga.sru · scope reports:read
NE-bilaga SRU files (INFO.SRU + BLANKETTER.SRU) as a zip, for upload at skatteverket.se.
The enskild firma's NE-bilaga as the two SRU files Skatteverket's filöverföring takes, ISO 8859-1 encoded and zipped, byte-identical to the dashboard download. The figures are those of GET /reports/ne-bilaga for the same period. The file carries the owner's full personnummer (the identifier Skatteverket files it under). Nothing is sent to Skatteverket: the user uploads the files, reviews and signs there.
Use when: The NE figures are reviewed and the files are to be uploaded at skatteverket.se.
Don't use for: Reading the figures (GET /reports/ne-bilaga), or an aktiebolag (GET /reports/ink2/sru).
Pitfalls
- The zip and its file name contain the owner's personnummer: store and forward it as personal data.
- Unzip and upload INFO.SRU and BLANKETTER.SRU under exactly those names; do not re-encode them to UTF-8.
- Only for enskild firma: another legal form answers 400 TAX_DECL_NE_WRONG_LEGAL_FORM.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | The fiscal period (räkenskapsår) id. |
Example response
{
"_note": "Returns application/zip as a binary download."
}
GET /api/v1/companies/:companyId/reports/periodisk-sammanstallning
reports.periodisk-sammanstallning · scope reports:read
Periodisk sammanställning (EU sales list): per-customer EU sales of goods, services and triangulation.
Builds the periodisk sammanställning for a month or quarter: one row per EU customer VAT number with varor, tjänster and trepartshandel amounts, plus warnings (missing or invalid VAT numbers, Swedish customers, credit notes), reconciled against the momsdeklaration (rutor 35, 38, 39) when the periods coincide. The SKV 574008 CSV for upload is served by GET /reports/periodisk-sammanstallning/csv. Read-only.
Use when: Before filing the periodisk sammanställning, or checking EU sales per customer against the momsdeklaration.
Don't use for: The momsdeklaration itself (GET /reports/vat-declaration) or domestic sales.
Pitfalls
- Warnings with level error block the CSV download (PS_REPORT_CSV_BLOCKED_BY_ERRORS): fix them first.
- Amounts are whole kronor, as the CSV takes them.
- The CSV also needs the tax contact (name, phone, email) on the company settings.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | yes | monthly (varor above the threshold) or quarterly. |
year | number | yes | Calendar year, 2000-2100. |
period | number | yes | 1-12 for monthly, 1-4 for quarterly. |
Response fields
| Name | Type |
|---|---|
period | object |
rows | object[] |
warnings | object[] |
Example request
{
"period_type": "quarterly",
"year": 2026,
"period": 2
}
Example response
{
"data": {
"period": {
"type": "quarterly",
"year": 2026,
"period": 2,
"start": "2026-04-01",
"end": "2026-06-30",
"label": "Kvartal 2 2026"
},
"rows": [
{
"country": "DE",
"vatNumber": "123456789",
"services": 42000,
"goods": 0,
"triangulation": 0,
"customerId": "4f1a…",
"customerName": "Beispiel GmbH",
"hasBlockingIssue": false
}
],
"warnings": [],
"totals": {
"services": 42000,
"goods": 0,
"triangulation": 0,
"grand": 42000,
"rowCount": 1
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/periodisk-sammanstallning/csv
reports.periodisk-sammanstallning.csv · scope reports:read
Periodisk sammanställning as the SKV 574008 CSV file, for upload at skatteverket.se.
The EU sales list for a month or quarter in the file format Skatteverket's e-tjänst takes (SKV 574008): a header with the org number, period code and tax contact, then one row per customer VAT number with varor, trepartshandel and tjänster in whole kronor. Refused while the report has blocking warnings or the tax contact is incomplete. Nothing is sent to Skatteverket.
Use when: The periodisk sammanställning is reviewed and is to be uploaded at skatteverket.se.
Don't use for: Reading the rows and warnings (GET /reports/periodisk-sammanstallning).
Pitfalls
- Blocking warnings answer 400 PS_REPORT_CSV_BLOCKED_BY_ERRORS: fix them (read the JSON) first.
- A missing tax contact (name, phone, email on the company settings) answers 400 PS_REPORT_MISSING_FILER_INFO.
- Refused while an SIE import is unfinished.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | yes | monthly (varor above the threshold) or quarterly. |
year | number | yes | Calendar year, 2000-2100. |
period | number | yes | 1-12 for monthly, 1-4 for quarterly. |
Example response
{
"_note": "Returns text/csv as a binary download."
}
GET /api/v1/companies/:companyId/reports/salary-journal
reports.salary-journal · scope payroll:read
Salary journal (lönejournal) for a year and optional month range.
Returns per-employee salary figures (gross / tax / net / avgifter / vacation accrual) summed across booked salary runs in year. Optional month_from and month_to limit the window. The output mirrors the dashboard's lönejournal export. ⚠️ KU (kontrolluppgift) preparation requires the FULL annual paid amount per employee: if any salary runs are in paid-but-unbooked state at KU time, generating KU from this report will understate wages (an SFL obligation breach). Confirm all paid runs are booked before using this report for KU.
Use when: Year-end KU preparation, employee comp reviews, reconciliation against the 7xxx wage accounts.
Don't use for: Per-run drill-down (use /salary-runs/{id} once the per-employee endpoint ships). AGI declarations (POST /salary-runs/{id}/generate-agi).
Pitfalls
yearis required (integer 2020-2100).- Only
bookedsalary runs are included:draft/review/approved/paidruns are excluded as they aren't legally final. paid-but-unbooked runs are EXCLUDED. This means the report reconciles cleanly against BAS 7xxx (the ledger), but an AGI-vs-ledger cross-check will show a gap until the run is booked. The AGI is filed atapproved/paid(Phase 5 PR-2 allows it fromreview), so reconciling AGI against this report requires waiting until every paid run is also booked.- month_from/month_to are 1-12 inclusive.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
year | number | yes | Payroll year, 2020-2100. Required. |
month_from | number | no | First month to include, 1-12 (inclusive). |
month_to | number | no | Last month to include, 1-12 (inclusive). |
Example response
{
"data": {
"year": 2026,
"employees": [],
"totals": {}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/sie-export
reports.sie-export · scope reports:read
SIE4 export (.se file) for a fiscal period.
Returns the period's SIE4 export as text/plain UTF-8. Includes #FNAMN / #ORGNR header, #KONTO chart, #IB/#UB opening + closing balances, #RES result-account totals, and every #VER + #TRANS verifikation in the period. The byte stream matches what the dashboard's /api/reports/sie-export produces.
Use when: Year-end accountant handoff, migration to another bookkeeping system, audit archival, BFL 7 kap räkenskapsinformation backup.
Don't use for: JSON drilldown of period entries (use /reports/journal-register). Full archive including documents (use /reports/full-archive: not yet on v1).
Pitfalls
period_idis required.- The response is text/plain with Content-Disposition: attachment: clients should treat as a binary download. Filename uses the pattern
export_{period_id}.se. - The compulsory #FORMAT PC8 tag is always present, but default byte encoding is UTF-8 (the de-facto cloud convention; importers detect encoding from the bytes). Pass
encoding=cp437for actual CP437 bytes, required by some legacy desktop bookkeeping software. - Only
postedentries are exported; drafts and reversed entries' originals are included but marked accordingly.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
exclude_closing | string | no | true leaves the year-end closing verifikat (source_type year_end) out of the #VER records, for importing into a system that books its own closing. Default: included. Archive the default, complete export. |
encoding | string | no | cp437 returns CP437 bytes for legacy desktop importers. Default: UTF-8. |
Example response
{
"_note": "Returns text/plain SIE4 content as binary download."
}
GET /api/v1/companies/:companyId/reports/supplier-ledger
reports.supplier-ledger · scope reports:read
Supplier ledger: unpaid supplier invoices with aging.
Returns the supplier-payable ledger as of as_of_date (defaults to today). Each supplier entry includes outstanding invoices grouped into aging buckets. Reconciles against BAS 2440.
Use when: AP workflow dashboards, due-date prioritisation, reconciliation against the 2440 trial-balance figure.
Don't use for: Listing all supplier invoices regardless of status (use /supplier-invoices). Initiating payment (the v1 surface does not expose payment files yet).
Pitfalls
as_of_dateis optional; formatYYYY-MM-DD. Defaults to today (UTC).- Only invoices with outstanding
remaining_amount > 0appear. Credited and fully-paid invoices are excluded.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
as_of_date | string | no | YYYY-MM-DD, a real calendar date between 2000 and next year. Default: today (UTC). |
Example response
{
"data": {
"as_of_date": "2026-05-31",
"suppliers": [],
"totals": {}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/trial-balance
reports.trial-balance · scope reports:read
Trial balance (huvudboksrapport) for a fiscal period.
Returns the per-account opening balance + period debit/credit + closing balance plus run-level totals and an isBalanced flag. The numbers come from the same lib/reports/trial-balance.ts generator the dashboard uses.
Use when: You need a snapshot of every active account's movement during a period: typically the first report an accountant checks before running balance sheet or income statement.
Don't use for: Reconciliation against AR/AP (use /reports/ar-ledger or /supplier-ledger). Specific account drill-in (use /reports/general-ledger with account_from/account_to filters).
Pitfalls
period_idis required as a query parameter.isBalanced=falsemeans the period has unbalanced postings: a data-integrity red flag. The lib generator rounds at the source so a true imbalance is rare; investigate immediately.- Closed/locked periods are still queryable: the report is read-only.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_id | string | yes | Fiscal period id (from GET /fiscal-periods). Required. |
Response fields
| Name | Type |
|---|---|
rows | object[] |
totalDebit | number |
totalCredit | number |
isBalanced | boolean |
Example response
{
"data": {
"rows": [
{
"account": "1930",
"account_name": "Företagskonto",
"opening_balance": 100000,
"period_debit": 25000,
"period_credit": 18000,
"closing_balance": 107000
}
],
"totalDebit": 25000,
"totalCredit": 25000,
"isBalanced": true
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/vacation-liability
reports.vacation-liability · scope payroll:read
Vacation liability (semesterlöneskuld) per employee at year-end.
Returns per-employee semesterlöneskuld balances as of year-end based on their vacation_rule (procentregeln / sammaloneregeln) and accrued days. For employees on procentregeln or sammaloneregeln the row total contributes to the BAS 2920 closing balance. Employees on none or semesterersattning are excluded because their cost is expensed immediately (no balance-sheet accrual): the BAS 2920 reconciliation against this report is therefore CORRECT whether or not the company has semesterersättning employees, since those employees contribute zero to both the report and the 2920 balance. Feeds the K2/K3 årsredovisning notes.
Use when: Year-end reconciliation between the accrued liability on 2920 and the per-employee detail. Audit prep.
Don't use for: Real-time accrual posting (handled per salary run). Vacation request management (not in scope for v1).
Pitfalls
yearis required.- Employees with vacation_rule = none or semesterersattning are excluded: they have no semesterlöneskuld liability.
- advanceVacationDebt (per row and in totals) is the förskottsskuld loaded as a cutover opening balance (SemL 29 a §): a receivable on the employee. totalLiability stays the booked 2920 + 2940 liability and is what bokslut and reconciliation use; netLiability subtracts the förskottsskuld for information only.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
year | number | yes | Year, 2020-2100. Required. |
Example response
{
"data": {
"year": 2026,
"employees": [],
"total_liability": 0
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/vat-declaration
reports.vat-declaration · scope reports:read
Swedish VAT declaration (momsdeklaration) for a period.
Computes momsdeklaration rutor for the given period_type / year / period. The result includes ruta 05 (domestic taxable sales), 10-12 (output VAT 25/12/6%), 20-24 (EU acquisitions of goods + tax on services from EU/non-EU), 30-32 (reverse-charge output VAT 25/12/6%), 39 (export), 40 (EU-services / momsfri försäljning), 48 (input VAT), 50 (import beskattningsunderlag), 60-62 (calculated output VAT on imports 25/12/6%), and 49 (moms att betala/återfå: the bottom line). Mapping rules match SKV 4700.
Use when: Submitting momsdeklaration to Skatteverket, reconciling VAT balances at month/quarter end, or building a VAT-payable dashboard.
Don't use for: Specific transaction VAT lookups (use /transactions/{id}). Period-mismatch reconciliation (use /reports/general-ledger filtered to 26xx accounts).
Pitfalls
period_type(monthly|quarterly|yearly),year, andperiodare all required.- For monthly: period is 1-12. For quarterly: period is 1-4. For yearly: period is 1.
accounting_methodis accepted for backward compatibility but has no effect on the figures: the declaration is a pure ledger projection, and the method (faktureringsmetoden vs kontantmetoden per ML 15 kap 8-11 §§, ML 2023:200) is already reflected in when VAT-bearing journal entries are posted.- Output ruta 49 = (10+11+12+30+31+32+60+61+62) − 48. Positive = pay; negative = refund.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | "yearly" | yes | Declaration period length. Required. |
year | number | yes | Calendar year of the period, 2000-2100. Required. |
period | number | yes | Period number within the year: 1-12 for monthly, 1-4 for quarterly, 1 for yearly. Required. |
accounting_method | "accrual" | "cash" | no | Accepted for backward compatibility; has no effect on the figures. |
Example response
{
"data": {
"period_type": "monthly",
"year": 2026,
"period": 4,
"rutor": {
"ruta05": 0,
"ruta10": 0,
"ruta11": 0,
"ruta12": 0,
"ruta20": 0,
"ruta21": 0,
"ruta22": 0,
"ruta23": 0,
"ruta24": 0,
"ruta30": 0,
"ruta31": 0,
"ruta32": 0,
"ruta39": 0,
"ruta40": 0,
"ruta48": 0,
"ruta50": 0,
"ruta60": 0,
"ruta61": 0,
"ruta62": 0,
"ruta49": 0
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/vat-declaration/eskd
reports.vat-declaration.eskd · scope reports:read
Momsdeklaration as an eSKD XML file, for "Deklarera via fil" at skatteverket.se.
The momsdeklaration for a period as the eSKDUpload v6.0 XML (ISO 8859-1) that Skatteverket's e-tjänst accepts as a file upload, computed purely from the bookkeeping: the same rutor as GET /reports/vat-declaration. No Skatteverket connection is needed and nothing is sent: the user uploads the file, reviews, signs and submits there.
Use when: The momsdeklaration is reviewed and the user files it by uploading a file rather than through the Skatteverket connection.
Don't use for: Reading the rutor (GET /reports/vat-declaration) or submitting through the Skatteverket API connection.
Pitfalls
- A missing or invalid org number on the company settings answers 400 VAT_ESKD_ORG_NUMBER_INVALID: the file would be rejected at upload.
- fiscal_period_id is for yearly (helårsmoms) with a broken räkenskapsår; it is ignored for monthly and quarterly.
- Refused while an SIE import is unfinished.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | "yearly" | yes | The momsperiod length. |
year | number | yes | Calendar year of the period; for yearly, the year the räkenskapsår ends. |
period | number | yes | 1-12 monthly, 1-4 quarterly, 1 yearly. |
fiscal_period_id | string | no | Yearly (helårsmoms) only: the räkenskapsår whose bounds the period takes, for a broken fiscal year. |
Example response
{
"_note": "Returns application/xml as a binary download."
}
GET /api/v1/companies/:companyId/reports/vat-declaration/filings
vat_filings.list · scope reports:read
List the calendar VAT periods the company has recorded as filed.
Returns every monthly or quarterly momsdeklaration period the company has on record as filed, newest first. source is skatteverket when the filing was confirmed by a Skatteverket kvittens through the connection, manual when a person or an API caller recorded it (POST on this path, or completing the period's moms deadline). reference is the Skatteverket reference typed at manual marking, if any. Local state: not a Skatteverket read.
Use when: Deciding which VAT period is next to prepare, checking whether a period was already filed before recomputing it, or reconciling a filing calendar against the books.
Don't use for: Reading what Skatteverket actually has on file (use /skatteverket/vat-declarations) or computing the declaration figures (use /reports/vat-declaration).
Pitfalls
- Helårsmoms (yearly) periods are not listed: their deadline is labelled per räkenskapsår and is completed from the calendar.
- An empty list means nothing is recorded, not that nothing was filed: companies that file on skatteverket.se by hand only get records when they mark the period (POST here or in the app).
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Response fields
| Name | Type |
|---|---|
[].deadline_id | string |
[].period_type | "monthly" | "quarterly" |
[].year | number |
[].period | number |
[].tax_period | string |
[].filed_on | string |
[].source | "skatteverket" | "manual" |
[].reference | string | null |
Example response
{
"data": [
{
"deadline_id": "11111111-1111-4111-8111-111111111111",
"period_type": "quarterly",
"year": 2026,
"period": 2,
"tax_period": "2026-Q2",
"filed_on": "2026-08-10",
"source": "manual",
"reference": null
}
],
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/reports/vat-declaration/settlement-proposal
reports.vat-settlement-proposal · scope reports:read
The proposed momsredovisning verifikat for a VAT period: clear 26xx to 2650 or 1650.
Builds the settlement entry for a momsperiod from the same ledger totals as the momsdeklaration: every output VAT account (261x-263x, reverse charge and import included) debited and every input VAT account (264x) credited by its period balance at exact öre, the net to 2650 (att betala, credit) or 1650 (att återfå, debit) at the whole-krona amount the declaration is filed with (ruta 49), and the öre gap on 3740. Dated the period's last day. existing_entries lists settlements already booked or drafted in the period (tagged vat_settlement or recognised by shape); booking_status sums them up. fingerprint identifies these exact lines. Read-only.
Use when: Before booking the VAT for a period (POST /vat/settlement), to review what will be posted.
Don't use for: The declaration rutor themselves (GET /reports/vat-declaration) or paying the VAT (the skattekonto payment is booked separately).
Pitfalls
- booking_status booked means a posted settlement exists: booking again is refused; reverse that verifikat first if the period must be re-booked.
- is_empty true means the period has no VAT to clear.
- The proposal clears the WHOLE period, not the change since an earlier settlement.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | "yearly" | yes | The momsperiod length. |
year | number | yes | Calendar year of the period; for yearly, the year the räkenskapsår ends. |
period | number | yes | 1-12 monthly, 1-4 quarterly, 1 yearly. |
fiscal_period_id | string | no | Yearly (helårsmoms) only: the räkenskapsår whose bounds the period takes, for a broken fiscal year. |
Response fields
| Name | Type | Description |
|---|---|---|
period | object | |
period_label | string | |
entry_date | string | |
description | string | |
lines | object[] | |
filed_net | number | Ruta 49 as filed, whole kronor; positive = att betala. |
rounding_amount | number | Signed öre gap balanced on 3740 (positive = credited). |
is_empty | boolean | |
existing_entries | object[] | |
booking_status | "booked" | "draft" | "none" | |
fingerprint | string |
Example request
{
"period_type": "quarterly",
"year": 2026,
"period": 1
}
Example response
{
"data": {
"period": {
"type": "quarterly",
"year": 2026,
"period": 1,
"start": "2026-01-01",
"end": "2026-03-31"
},
"period_label": "Kvartal 1 2026",
"entry_date": "2026-03-31",
"description": "Momsredovisning Kvartal 1 2026",
"lines": [
{
"account_number": "2611",
"debit_amount": 25000,
"credit_amount": 0
},
{
"account_number": "2641",
"debit_amount": 0,
"credit_amount": 6250.4
},
{
"account_number": "2650",
"debit_amount": 0,
"credit_amount": 18749,
"line_description": "Moms att betala"
},
{
"account_number": "3740",
"debit_amount": 0,
"credit_amount": 0.6,
"line_description": "Öres- och kronutjämning"
}
],
"filed_net": 18749,
"rounding_amount": 0.6,
"is_empty": false,
"existing_entries": [],
"booking_status": "none",
"fingerprint": "3f9a…"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/reports/vat-declaration/filings
vat_filings.mark · scope bookkeeping:write
Record that a VAT period was filed outside the Skatteverket connection.
Marks a monthly or quarterly momsdeklaration period as filed on filed_on (Swedish calendar date), optionally with Skatteverket's reference (kvittensnummer). Completes the period's moms deadline with status submitted, creating the deadline row when the company has none for the period. Nothing is sent to Skatteverket. Idempotent: marking an already-marked period updates its date and reference; a period already confirmed at Skatteverket is returned unchanged (changed: false). Dry-runnable.
Use when: The declaration was filed on skatteverket.se by hand, by an ombud, or from another system, and the books should know the period is done so the next period opens by default.
Don't use for: Filing the declaration itself: that is the BankID-signed flow (accounted_vat_declaration_submit / the Skatteverket panel). Yearly (helårsmoms) periods: complete the calendar deadline instead.
Pitfalls
- The period must have ended and
filed_onmust fall after the period's last day and no later than today (Swedish date): otherwise 400 with VAT_FILING_PERIOD_NOT_ENDED, VAT_FILING_DATE_BEFORE_PERIOD_END or VAT_FILING_DATE_IN_FUTURE. - Omitting
referencekeeps a previously stored reference; pass null to clear it. - This records a fact about the books, it does not verify anything at Skatteverket. Use /skatteverket/vat-declarations to check what was actually received.
- A 409 CONFLICT means the deadline row changed while it was being marked (for example a deadline regeneration ran at the same moment). Nothing was written; retry the same request.
Risk: low · Idempotent: yes · Reversible: yes · Dry-run supported: yes
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
dry_run | string | no | true (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits. |
Request body
| Name | Type | Required |
|---|---|---|
period_type | "monthly" | "quarterly" | yes |
year | number | yes |
period | number | yes |
filed_on | string | yes |
reference | string | null | no |
Response fields
| Name | Type |
|---|---|
deadline_id | string |
period_type | "monthly" | "quarterly" |
year | number |
period | number |
tax_period | string |
filed_on | string |
source | "skatteverket" | "manual" |
reference | string | null |
created | boolean |
changed | boolean |
Example request
{
"period_type": "quarterly",
"year": 2026,
"period": 2,
"filed_on": "2026-08-10",
"reference": "ABC123"
}
Example response
{
"data": {
"deadline_id": "11111111-1111-4111-8111-111111111111",
"period_type": "quarterly",
"year": 2026,
"period": 2,
"tax_period": "2026-Q2",
"filed_on": "2026-08-10",
"source": "manual",
"reference": "ABC123",
"created": false,
"changed": true
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/vat/settlement
vat.book-settlement · scope bookkeeping:write
Book the momsredovisning verifikat for a VAT period, exactly as the proposal gives it.
Posts the settlement proposal of GET /reports/vat-declaration/settlement-proposal as a verifikat (source_type vat_settlement) through the bookkeeping engine: 26xx cleared, the net on 2650 or 1650 at the filed whole-krona amount, the öre gap on 3740, dated the period's last day. The lines are the server's, never the caller's. Refused when a settlement is already posted in the period, when there is nothing to clear, when expected_fingerprint no longer matches, or when the date is locked. The declaration projection excludes vat_settlement entries, so the momsdeklaration does not change. Idempotent. Dry-runnable: the dry run previews the verifikat and writes nothing.
Use when: The VAT period is reviewed (and usually filed) and the 26xx accounts should be cleared to the skattekonto liability.
Don't use for: Filing the momsdeklaration with Skatteverket (the eSKD file or the Skatteverket connection), booking the payment to the skattekonto, or custom settlement lines (post an ordinary verifikat with POST /journal-entries).
Pitfalls
- A posted settlement in the period answers 409 VAT_SETTLEMENT_ALREADY_BOOKED with details.journal_entry_id: reverse it first if the period must be re-booked.
- Pass expected_fingerprint from the proposal you reviewed: if the ledger changed since, 409 VAT_SETTLEMENT_PROPOSAL_CHANGED instead of booking different lines.
- A locked or closed period, or a date on or before the company lock date, answers 400 PERIOD_LOCKED; no voucher number is spent.
- A posted verifikat is permanent: undo it with storno (POST /journal-entries/{id}/reverse), never by editing.
Risk: high · Idempotent: yes · Reversible: no · Dry-run supported: yes
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
dry_run | string | no | true (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | "yearly" | yes | The momsperiod length. |
year | number | yes | Calendar year of the period; for yearly, the year the räkenskapsår ends. |
period | number | yes | 1-12 monthly, 1-4 quarterly, 1 yearly. |
fiscal_period_id | string | no | Yearly (helårsmoms) only: the räkenskapsår whose bounds the period takes, for a broken fiscal year. |
expected_fingerprint | string | no | fingerprint from the proposal you reviewed. The booking is refused if the proposal changed since. |
Response fields
| Name | Type |
|---|---|
journal_entry_id | string |
voucher_series | string | null |
voucher_number | number | null |
entry_date | string |
period_label | string |
filed_net | number |
rounding_amount | number |
Example request
{
"period_type": "quarterly",
"year": 2026,
"period": 1,
"expected_fingerprint": "3f9a…"
}
Example response
{
"data": {
"journal_entry_id": "9a0b…",
"voucher_series": "A",
"voucher_number": 57,
"entry_date": "2026-03-31",
"period_label": "Kvartal 1 2026",
"filed_net": 18749,
"rounding_amount": 0.6
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
DELETE /api/v1/companies/:companyId/reports/vat-declaration/filings
vat_filings.unmark · scope bookkeeping:write
Undo a manual "filed" mark on a VAT period.
Puts the period's moms deadline back to pending and removes the stored reference. Query params: period_type (monthly|quarterly), year, period. A period confirmed at Skatteverket through the connection is refused with 409 VAT_FILING_CONFIRMED_BY_SKATTEVERKET; a period with no filing record answers 404 VAT_FILING_NOT_FOUND. Dry-runnable.
Use when: A period was marked as filed by mistake.
Don't use for: Withdrawing or correcting a declaration at Skatteverket: that is a new declaration for the same period, filed through the ordinary flow.
Pitfalls
- Only manual marks can be undone; a Skatteverket kvittens is a fact this endpoint does not erase.
Risk: low · Idempotent: yes · Reversible: yes · Dry-run supported: yes
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
period_type | "monthly" | "quarterly" | yes | |
year | number | yes | |
period | number | yes | |
dry_run | string | no | true (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits. |
Response fields
| Name | Type |
|---|---|
deadline_id | string |
unmarked | true |
Example request
{
"period_type": "quarterly",
"year": 2026,
"period": 2
}
Example response
{
"data": {
"deadline_id": "11111111-1111-4111-8111-111111111111",
"unmarked": true
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}