Menu

Accounts

The chart of accounts (BAS): read, add, edit, activate, deactivate and delete unused accounts.

Endpoints


GET /api/v1/companies/:companyId/accounts

accounts.list · scope reports:read

List chart-of-accounts entries (BAS chart).

Returns the company's own chart of accounts (kontoplan), ordered by account_number, which is the BAS sequence (a longer sub-account number such as 19301 sorts directly after 1930). This is not the full BAS 2026 catalogue: a new company starts with a small set of accounts seeded for its company form, and standard BAS accounts join the chart when the user activates them, when an import brings them in, or automatically the first time a verifikat posts to one. Filter with ?class=<0-9>, the first digit of account_number: 1 assets; 2 equity, untaxed reserves and liabilities; 3 operating revenue; 4 goods, materials and subcontracted services; 5 external expenses for premises, leasing, energy, consumables, repairs, vehicles, freight, travel, and advertising and PR; 6 other external expenses such as selling costs, office supplies, telecom, insurance, administration, accounting, IT and consulting services, and hired staff; 7 personnel costs, plus write-downs and depreciation (77xx-78xx); 8 financial items, year-end appropriations (88xx), and tax and the year's result (89xx). Classes 0 and 9 are outside BAS's 1-8 (free for company use) and appear only on internal accounts, typically carried over from an imported chart. Only active accounts are returned by default; pass ?active=false to include deactivated ones.

Use when: You need account numbers and names to render verifikation tables, build a custom report, check that an account is active before booking to it, or look up an account's type, normal balance, SRU code or VAT defaults.

Don't use for: Fetching balances: use the trial-balance report. Creating, editing, deactivating or deleting accounts: POST /accounts, PATCH and DELETE /accounts/{number}, POST /accounts/activate and /accounts/deactivate.

Pitfalls

  • account_number is a STRING: "1930", not 1930. BAS numbers have four digits; a chart imported from another system can also carry longer sub-account numbers such as "19301".
  • An account missing from this list is not necessarily unusable. Posting to a standard BAS 2026 account that is not in the chart adds it automatically; posting to a deactivated account, or to a non-BAS number the chart does not contain, fails with ACCOUNTS_NOT_IN_CHART.
  • is_system_account=true marks the accounts seeded when the company was created (such as 1510, 1930, 2440, 2611 and 3001). They cannot be deleted and bulk deactivation skips them, but they can still be renamed and deactivated one at a time.
  • normal_balance belongs to the account, not to account_type: contra accounts go against their type, such as 1219 (accumulated depreciation, an asset with a credit balance) and 3730 (discounts given, revenue with a debit balance).
  • default_vat_rate is a fraction (0, 0.06, 0.12 or 0.25), not a percentage. default_vat_treatment overrides the built-in BAS mapping for the momsdeklaration and is null unless someone set it; it can only be set on class 3 (sales treatments) and classes 4-6 (reverse-charge purchase treatments).
  • sort_order is a stored display hint, not a sequence to rely on: every account seeded at company creation carries 0. The list already comes in BAS order.
  • Deactivated accounts are excluded by default; pass ?active=false to include them. A deactivated account keeps its history and balances but cannot be used on new verifikat.

Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no

Query parameters

NameTypeRequiredDescription
classstringnoAccount class, the first digit of account_number (0-9). BAS uses 1-8; 0 and 9 appear only on internal accounts, typically carried over from an imported chart.
active"true" | "false"nofalse also returns deactivated accounts. Default: active accounts only.

Response fields

NameType
accounts[].account_numberstring
accounts[].account_namestring
accounts[].account_classnumber
accounts[].account_groupstring
accounts[].account_type"asset" | "equity" | "liability" | "untaxed_reserves" | "revenue" | "expense"
accounts[].normal_balance"debit" | "credit"
accounts[].is_system_accountboolean
accounts[].is_activeboolean
accounts[].descriptionstring | null
accounts[].default_vat_codestring | null
accounts[].default_vat_ratenumber | null
accounts[].default_vat_treatment"standard_25" | "reduced_12" | "reduced_6" | "exempt" | "reverse_charge_domestic" | "reverse_charge_eu_goods" | "reverse_charge_eu_services" | "reverse_charge_non_eu_services" | "export_goods" | "export_services" | "vmb" | "rental_voluntary" | "oss" | "triangulation_eu_goods" | "own_use" | "import_goods" | null
accounts[].sru_codestring | null
accounts[].sort_ordernumber | null

Example response

{
  "data": {
    "accounts": [
      {
        "account_number": "1930",
        "account_name": "Företagskonto / checkkonto",
        "account_class": 1,
        "account_group": "19",
        "account_type": "asset",
        "normal_balance": "debit",
        "is_system_account": true,
        "is_active": true,
        "description": null,
        "default_vat_code": null,
        "default_vat_rate": null,
        "default_vat_treatment": null,
        "sru_code": "7281",
        "sort_order": 0
      },
      {
        "account_number": "3001",
        "account_name": "Försäljning inom Sverige, 25 % moms",
        "account_class": 3,
        "account_group": "30",
        "account_type": "revenue",
        "normal_balance": "credit",
        "is_system_account": true,
        "is_active": true,
        "description": null,
        "default_vat_code": null,
        "default_vat_rate": 0.25,
        "default_vat_treatment": null,
        "sru_code": "7410",
        "sort_order": 0
      }
    ]
  },
  "meta": {
    "request_id": "req_…",
    "api_version": "2026-05-12"
  }
}

POST /api/v1/companies/:companyId/accounts

accounts.create · scope bookkeeping:write

Add an account to the chart of accounts (kontoplan).

Adds an account to the company's kontoplan. A BAS 2026 number needs nothing but the number: name, account_type, normal_balance, description and SRU code are prefilled from the catalogue, and anything you send wins. A number outside BAS 2026 must name account_name, account_type and normal_balance. account_class and account_group derive from the number. A default_vat_treatment without a default_vat_rate derives the booking rate. Idempotent. Dry-runnable.

Use when: A verifikat needs an account the chart does not carry: a company-specific sub-account, or a BAS account the company has not used yet.

Don't use for: Reactivating a deactivated account (PATCH is_active=true, or POST /accounts/activate) or bulk-adding standard BAS accounts (POST /accounts/activate).

Pitfalls

  • account_number is a STRING of exactly 4 digits: "5410", not 5410.
  • The account_type must fit the class, the first digit: 1 asset; 2 equity, liability or untaxed_reserves (21xx only); 3 revenue; 4-7 expense; 8 revenue or expense. A mismatch returns 400 ACCOUNT_TYPE_CLASS_CONFLICT.
  • A number already in the chart returns 409 ACCOUNT_EXISTS, or ACCOUNT_EXISTS_INACTIVE when it was deactivated: reactivate it instead.
  • default_vat_rate is a fraction (0, 0.06, 0.12, 0.25), not a percentage.
  • vat_box (momsruta override) only fits 26xx VAT accounts other than 2650.

Risk: low · Idempotent: yes · Reversible: yes · Dry-run supported: yes

Query parameters

NameTypeRequiredDescription
dry_runstringnotrue (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits.

Request body

NameTypeRequiredDescription
account_numberstringyes4-digit number, e.g. "5410".
account_namestringno
account_type"asset" | "equity" | "liability" | "revenue" | "expense" | "untaxed_reserves"nountaxed_reserves only for 21xx.
normal_balance"debit" | "credit"no
descriptionstringno
default_vat_codestringno
default_vat_rate0noFraction (0.25 = 25%). Livsmedel 0.06 from 2026-04-01 through 2027-12-31, then 0.12.
default_vat_treatment"standard_25"no
vat_box"10"no
sru_codestringno

Response fields

NameType
idstring
account_numberstring
account_namestring
account_classnumber
account_groupstring
account_type"asset" | "equity" | "liability" | "revenue" | "expense" | "untaxed_reserves"
normal_balance"debit" | "credit"
plan_typestring | null
is_activeboolean
is_system_accountboolean
descriptionstring | null
default_vat_codestring | null
default_vat_ratenumber | null
default_vat_treatment"standard_25" | "reduced_12" | "reduced_6" | "exempt" | "reverse_charge_domestic" | "reverse_charge_eu_goods" | "reverse_charge_eu_services" | "reverse_charge_non_eu_services" | "export_goods" | "export_services" | "vmb" | "rental_voluntary" | "oss" | "triangulation_eu_goods" | "own_use" | "import_goods" | null
vat_box"10" | "11" | "12" | "30" | "31" | "32" | "48" | "60" | "61" | "62" | null
sru_codestring | null
sort_ordernumber | null

Example request

{
  "account_number": "5410"
}

Example response

{
  "data": {
    "id": "8d0e…",
    "account_number": "5410",
    "account_name": "Förbrukningsinventarier",
    "account_class": 5,
    "account_group": "54",
    "account_type": "expense",
    "normal_balance": "debit",
    "plan_type": "full_bas",
    "is_active": true,
    "is_system_account": false,
    "description": null,
    "default_vat_code": null,
    "default_vat_rate": null,
    "default_vat_treatment": null,
    "vat_box": null,
    "sru_code": "7321",
    "sort_order": 5410
  },
  "meta": {
    "request_id": "req_…",
    "api_version": "2026-05-12"
  }
}

POST /api/v1/companies/:companyId/accounts/activate

accounts.activate · scope bookkeeping:write

Activate BAS accounts in bulk.

Makes each listed account bookable: a standard BAS 2026 number missing from the chart is added from the catalogue, a deactivated account is reactivated, an active one is skipped. Numbers that are neither in the chart nor in BAS 2026 are reported in unknown, not refused: add those one at a time with POST /accounts. Idempotent. Dry-runnable.

Use when: A booking failed with ACCOUNTS_NOT_IN_CHART, or you want a set of standard BAS accounts available before importing or booking.

Don't use for: A company-specific account outside BAS 2026 (POST /accounts with name, type and normal balance).

Pitfalls

  • account_numbers are STRINGS: ["5410", "6570"].
  • Up to 2000 numbers per call; duplicates are counted once.
  • Check unknown in the answer: those numbers were not added.

Risk: low · Idempotent: yes · Reversible: yes · Dry-run supported: yes

Query parameters

NameTypeRequiredDescription
dry_runstringnotrue (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits.

Request body

NameTypeRequired
account_numbersstring[]yes

Response fields

NameType
accountsobject[]
activatednumber
reactivatednumber
skippednumber
unknownstring[]

Example request

{
  "account_numbers": [
    "5410",
    "6570"
  ]
}

Example response

{
  "data": {
    "accounts": [
      {
        "account_number": "5410"
      }
    ],
    "activated": 1,
    "reactivated": 0,
    "skipped": 1,
    "unknown": []
  },
  "meta": {
    "request_id": "req_…",
    "api_version": "2026-05-12"
  }
}

POST /api/v1/companies/:companyId/accounts/deactivate

accounts.deactivate · scope bookkeeping:write

Deactivate accounts in bulk.

Deactivates each listed account so it stops being offered for new bookings; history and balances stay. System accounts are always skipped, and accounts with journal lines are skipped unless include_used=true (deactivating a used account hides its balance from the kontoplan). Already inactive numbers are counted, numbers not in the chart reported in unknown. Idempotent. Dry-runnable.

Use when: Tidying a chart imported from a previous system, where hundreds of accounts were never posted to.

Don't use for: Removing accounts for good (DELETE /accounts/{number}, unused accounts only).

Pitfalls

  • account_numbers are STRINGS.
  • include_used defaults to false: used accounts come back in skipped_used.
  • Reactivate with POST /accounts/activate or PATCH is_active=true.

Risk: low · Idempotent: yes · Reversible: yes · Dry-run supported: yes

Query parameters

NameTypeRequiredDescription
dry_runstringnotrue (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits.

Request body

NameTypeRequiredDescription
account_numbersstring[]yes
include_usedbooleannoAlso deactivate accounts with journal lines. Default false.

Response fields

NameType
accountsobject[]
deactivatednumber
skipped_systemstring[]
skipped_usedstring[]
skipped_inactivenumber
unknownstring[]

Example request

{
  "account_numbers": [
    "6991",
    "7699"
  ]
}

Example response

{
  "data": {
    "accounts": [
      {
        "account_number": "6991"
      }
    ],
    "deactivated": 1,
    "skipped_system": [],
    "skipped_used": [
      "7699"
    ],
    "skipped_inactive": 0,
    "unknown": []
  },
  "meta": {
    "request_id": "req_…",
    "api_version": "2026-05-12"
  }
}

PATCH /api/v1/companies/:companyId/accounts/:number

accounts.update · scope bookkeeping:write

Edit or deactivate an account in the chart of accounts.

Sparse update of one kontoplan account: name, description, VAT defaults (code, booking rate, treatment), momsruta override (vat_box), SRU code and is_active (false deactivates it: history and balances stay, new verifikat cannot use it). An empty string or null clears a text field. The number, class, type and normal balance are fixed: an account that should be something else is a new account. A treatment without a rate derives the booking rate only when none is stored. Idempotent. Dry-runnable.

Use when: An account needs a clearer name, other VAT defaults or SRU mapping, or should stop (or start again) being offered for bookings.

Don't use for: Removing an unused account (DELETE) or deactivating many at once (POST /accounts/deactivate).

Pitfalls

  • The path takes the account number as a STRING, e.g. /accounts/5410.
  • At least one field must be sent: an empty body returns 400 ACCOUNT_NOTHING_TO_UPDATE.
  • default_vat_treatment must fit the class (400 ACCOUNT_VAT_TREATMENT_CLASS); null restores the BAS mapping.
  • vat_box only fits 26xx VAT accounts other than 2650; null restores the BAS momsruta.

Risk: low · Idempotent: yes · Reversible: yes · Dry-run supported: yes

Query parameters

NameTypeRequiredDescription
dry_runstringnotrue (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits.

Request body

NameTypeRequired
account_namestringno
descriptionstringno
default_vat_codestringno
default_vat_rate0no
default_vat_treatment"standard_25"no
vat_box"10"no
sru_codestringno
is_activebooleanno

Response fields

NameType
idstring
account_numberstring
account_namestring
account_classnumber
account_groupstring
account_type"asset" | "equity" | "liability" | "revenue" | "expense" | "untaxed_reserves"
normal_balance"debit" | "credit"
plan_typestring | null
is_activeboolean
is_system_accountboolean
descriptionstring | null
default_vat_codestring | null
default_vat_ratenumber | null
default_vat_treatment"standard_25" | "reduced_12" | "reduced_6" | "exempt" | "reverse_charge_domestic" | "reverse_charge_eu_goods" | "reverse_charge_eu_services" | "reverse_charge_non_eu_services" | "export_goods" | "export_services" | "vmb" | "rental_voluntary" | "oss" | "triangulation_eu_goods" | "own_use" | "import_goods" | null
vat_box"10" | "11" | "12" | "30" | "31" | "32" | "48" | "60" | "61" | "62" | null
sru_codestring | null
sort_ordernumber | null

Example request

{
  "account_name": "Verktyg och inventarier"
}

Example response

{
  "data": {
    "id": "8d0e…",
    "account_number": "5410",
    "account_name": "Verktyg och inventarier",
    "account_class": 5,
    "account_group": "54",
    "account_type": "expense",
    "normal_balance": "debit",
    "plan_type": "full_bas",
    "is_active": true,
    "is_system_account": false,
    "description": null,
    "default_vat_code": null,
    "default_vat_rate": null,
    "default_vat_treatment": null,
    "vat_box": null,
    "sru_code": "7321",
    "sort_order": 5410
  },
  "meta": {
    "request_id": "req_…",
    "api_version": "2026-05-12"
  }
}

DELETE /api/v1/companies/:companyId/accounts/:number

accounts.delete · scope bookkeeping:write

Delete an account nothing has been booked on.

Removes an account from the kontoplan. Refused for system accounts and for any account with journal lines in this company, on any entry status including drafts (BFL: a verifikat is immutable and its lines must keep resolving to an account). Deactivate those with PATCH is_active=false instead. Idempotent. Dry-runnable.

Use when: An account was added by mistake, or an imported chart carries accounts the company never used.

Don't use for: Retiring an account that has been used: deactivate it (PATCH is_active=false).

Pitfalls

  • An account with any journal line returns 409 ACCOUNT_IN_USE with details.usage_count.
  • System accounts (seeded at company creation) return 400 ACCOUNT_SYSTEM_DELETE.
  • A standard BAS account can be re-added later with POST /accounts or POST /accounts/activate.

Risk: medium · Idempotent: yes · Reversible: no · Dry-run supported: yes

Query parameters

NameTypeRequiredDescription
dry_runstringnotrue (any case) previews the write without committing it, like the X-Dry-Run: true header. Any other value commits.

Response fields

NameType
deletedtrue
account_numberstring

Example response

{
  "data": {
    "deleted": true,
    "account_number": "5410"
  },
  "meta": {
    "request_id": "req_…",
    "api_version": "2026-05-12"
  }
}