Menu
Cookbooks
API reference
- Overview
- Companies
- Capabilities
- Measures
- Packages
- Unexplained
- Liquidity forecast
- Portfolio
- Customers
- Invoices
- Collections
- Articles
- Set-offs
- Suppliers
- Supplier invoices
- Supplier payment files
- Bank payments
- Expense claims
- Transactions
- Reconciliation
- Bank accounts
- POS sales
- Webshop orders
- Journal entries
- Voucher gap explanations
- Fiscal periods
- Accounts
- Accrual schedules
- Agreements and commitments
- Tax loss carry-forwards
- Fixed assets
- Documents
- Signing requests
- Company registers
- Capital events
- Owner tax
- Inbox items
- Dimensions
- Employees
- Salary runs
- Reports
- Budgets
- Imports
- Compliance check
- Skatteverket
- Peppol
- Webhooks
- Operations
- Pending operations
- Health
- API key
- Service accounts
Company registers
Bolaget: the aktiebok (share register) as of any date with its dated history, the share classes and their förbehåll, the board, VD, firmatecknare and revisor over time, the firmateckning, and the verkliga huvudmän derived from the aktiebok. Entries are permanent: a rattelse entry voids one. A personnummer is never sent or answered. The meetings (stämmor, styrelsemöten, per capsulam) with their decisions and minutes; an adopted election changes the roles when a person signs the minutes in Accounted.
Endpoints
GET/api/v1/companies/:companyId/beneficial-owners: Read the verkliga huvudmän: the proposal from the aktiebok, the confirmed set and the record of assessments.GET/api/v1/companies/:companyId/company-roles: List the company's roles over time (board, VD, firmatecknare, revisor, verkliga huvudmän) and the firmateckning.GET/api/v1/companies/:companyId/corporate-meetings: List the company's bolagsstämmor, styrelsemöten and per capsulam decisions, newest first.GET/api/v1/companies/:companyId/corporate-meetings/:id: Read one meeting: its minutes paragraph by paragraph, röstlängd, attendance, signers, effects on the roles and warnings.GET/api/v1/companies/:companyId/share-register: Read the aktiebok as of a date: holders with shares, votes and percent, share numbers, classes and notes.GET/api/v1/companies/:companyId/share-register/events: List every aktiebok entry in entry order, each with a Swedish sentence and whether a rättelse voided it.POST/api/v1/companies/:companyId/beneficial-owners/assessments: Record an assessment of the verkliga huvudmän (LRVH 2:1): who they are and why, or that there is none.POST/api/v1/companies/:companyId/company-roles: Add a role from a date: board member, chair, suppleant, VD, vice VD, firmatecknare, revisor or contact person.POST/api/v1/companies/:companyId/company-roles/:id/end: End a role on a date (the last day in it). The row is kept.POST/api/v1/companies/:companyId/corporate-meetings: Plan a meeting: an årsstämma (prefilled from the årsredovisning and the roles), an extra stämma, a styrelsemöte or a per capsulam decision.POST/api/v1/companies/:companyId/corporate-meetings/:id/decisions: Add or change a decision (paragraph) in a meeting's unsigned minutes, with its terms per kind.POST/api/v1/companies/:companyId/corporate-meetings/:id/hold: Mark a meeting as held: a board meeting takes its minutes number, an årsstämma records its date on the årsredovisning.POST/api/v1/companies/:companyId/share-classes: Add a share class with its votes per share and the förbehåll of the bolagsordning.POST/api/v1/companies/:companyId/share-register/events: Add a dated entry to the aktiebok: an issue, a transfer, a cancellation, a conversion, a split, an aktiebrev, a pledge or a note.POST/api/v1/companies/:companyId/signatory-rules: Set the firmateckning from a date; the rule in force ends the day before.PATCH/api/v1/companies/:companyId/corporate-meetings/:id: Change a meeting whose minutes are not signed: date, place, chair, protokollförare, justerare, kallelse, attendance or röstlängd presence.PATCH/api/v1/companies/:companyId/share-classes/:id: Change a share class's name, votes per share or förbehåll; its code stays.
GET /api/v1/companies/:companyId/beneficial-owners
beneficial-owners.get · scope companies:read
Read the verkliga huvudmän: the proposal from the aktiebok, the confirmed set and the record of assessments.
The proposal names every natural person with more than 25 % of the votes (LRVH 1:3) and lists companies above 25 % for investigation. Close family holdings (1:5) and control by agreement are for the company to confirm. differs is true when a new assessment is due.
Use when: A bank asks for the company's beneficial owners, or ownership has changed.
Don't use for: Filing with Bolagsverket: that is done in Bolagsverket's e-service (filing_url) by an authorised representative.
Pitfalls
- The proposal is not the answer: a person confirms it with gnubok_confirm_beneficial_owners.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
as_of | string | no | The day the answer is for (YYYY-MM-DD). Default today. |
Response fields
| Name | Type | Description |
|---|---|---|
proposal | object | |
confirmed | object[] | |
assessments | object[] | |
differs | boolean | The proposal names other persons than those confirmed: a new assessment is due. |
filing_url | string |
Example response
{
"data": {
"proposal": {
"owners": [
{
"name": "Anna Ek",
"votes_pct": 60
}
],
"conclusion": "owners_identified"
},
"differs": true
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/company-roles
company-roles.list · scope companies:read
List the company's roles over time (board, VD, firmatecknare, revisor, verkliga huvudmän) and the firmateckning.
Every role with valid_from and valid_to, and whether it holds on as_of; the firmateckning text in force. The first read for a company without roles seeds them from the registry data Accounted already holds (no registry call).
Use when: You need who is on the board, who is VD, who signs for the company or who the beneficial owners are.
Don't use for: Shareholdings (GET /share-register).
Pitfalls
- A role with source registry_tic came from the registry snapshot; check it against Bolagsverket before relying on it for a filing.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
as_of | string | no | The day the answer is for (YYYY-MM-DD). Default today. |
Response fields
| Name | Type | Description |
|---|---|---|
as_of | string | |
signatory_rule | string | null | The firmateckning in force on as_of. |
roles | object[] | |
signatory_rules | object[] |
Example response
{
"data": {
"as_of": "2026-10-29",
"signatory_rule": "Firman tecknas av styrelsen",
"roles": [
{
"company_role_id": "1f3c…",
"name": "Anna Ek",
"role": "styrelseledamot",
"active": true
}
]
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/corporate-meetings
corporate-meetings.list · scope companies:read
List the company's bolagsstämmor, styrelsemöten and per capsulam decisions, newest first.
Each meeting with its kind, date, place, status (draft, held, signed) and board minutes number (ABL 8:26). Filter by kind or fiscal year.
Use when: You need the company's meetings, the årsstämma for a year, or the latest board minutes.
Don't use for: The decisions and minutes of one meeting (GET /corporate-meetings/{id}).
Pitfalls
- A draft is a plan; only held and signed meetings took place.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
kind | "arsstamma" | "extra_stamma" | "styrelsemote" | "per_capsulam" | no | arsstamma, extra_stamma, styrelsemote or per_capsulam. |
fiscal_period_id | string | no | An årsstämma's fiscal year. |
Response fields
| Name | Type | Description |
|---|---|---|
meetings[].corporate_meeting_id | string | |
meetings[].kind | "arsstamma" | "extra_stamma" | "styrelsemote" | "per_capsulam" | |
meetings[].kind_label | string | |
meetings[].organ | "bolagsstamma" | "styrelse" | Whose decisions: bolagsstamma (shareholders) or styrelse (board). |
meetings[].title | string | |
meetings[].sequence_number | number | null | Board minutes number (ABL 8:26), given when the meeting is held. |
meetings[].meeting_date | string | |
meetings[].place | string | null | |
meetings[].is_digital | boolean | |
meetings[].status | "draft" | "held" | "signed" | draft, held (minutes open) or signed (frozen). |
meetings[].fiscal_period_id | string | null | |
meetings[].signing_pending | boolean | |
meetings[].signed_at | string | null |
Example response
{
"data": {
"meetings": [
{
"corporate_meeting_id": "4b1e…",
"kind": "arsstamma",
"title": "Årsstämma 2027-05-10",
"status": "signed"
}
]
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/corporate-meetings/:id
corporate-meetings.get · scope companies:read
Read one meeting: its minutes paragraph by paragraph, röstlängd, attendance, signers, effects on the roles and warnings.
Each decision with its terms (payload) and the sentence the minutes print; the röstlängd from the aktiebok on the meeting day (ABL 7:48); who signs (protokollförare, ordförande, justerare, or all shareholders per capsulam); the role changes an adopted election makes when the minutes are signed; and what a person should check (warnings).
Use when: You need what a stämma or the board decided, the dividend per share and betalningsdag, or what is missing before signing.
Don't use for: Signing the minutes: a person signs with BankID or uploads the signed copy in Accounted.
Pitfalls
- Names only: no personnummer, no email addresses.
- register_effects.planned is a preview until the minutes are signed.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Response fields
| Name | Type | Description |
|---|---|---|
corporate_meeting_id | string | |
kind | "arsstamma" | "extra_stamma" | "styrelsemote" | "per_capsulam" | |
kind_label | string | |
organ | "bolagsstamma" | "styrelse" | Whose decisions: bolagsstamma (shareholders) or styrelse (board). |
title | string | |
sequence_number | number | null | Board minutes number (ABL 8:26), given when the meeting is held. |
meeting_date | string | |
place | string | null | |
is_digital | boolean | |
status | "draft" | "held" | "signed" | draft, held (minutes open) or signed (frozen). |
fiscal_period_id | string | null | |
signing_pending | boolean | |
signed_at | string | null | |
meeting_time | string | null | |
chair | object | null | |
secretary | object | null | |
adjusters | object[] | Justerare. |
kallelse_date | string | null | |
kallelse_method | string | null | |
kallelse_window | object | null | When the kallelse is sent (ABL 7:18-20). |
fiscal_period | object | null | |
voting_list | object | null | Röstlängd: the aktiebok on the meeting day (ABL 7:48), names only. |
present | object | null | |
attendees | object[] | |
notes | string | null | |
held_at | string | null | |
signature_names | string | null | |
minutes_document_id | string | null | |
signed_document_id | string | null | |
signing_request_id | string | null | |
decisions | object[] | |
justering | "named" | "not_needed_holds_all_shares" | "not_needed_single_member_board" | "covered_by_board_signatures" | "not_applicable" | "missing" | |
signers | object[] | |
register_effects | object | |
warnings | object[] | |
signing | object | null |
Example response
{
"data": {
"corporate_meeting_id": "4b1e…",
"kind": "arsstamma",
"status": "held",
"decisions": [
{
"item_number": 8,
"kind": "faststallande_rr_br",
"text_rendered": "Stämman fastställde resultaträkningen och balansräkningen för räkenskapsåret 2026-01-01 till 2026-12-31."
}
]
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/share-register
share-register.get · scope companies:read
Read the aktiebok as of a date: holders with shares, votes and percent, share numbers, classes and notes.
The share register (ABL 5 kap.) replayed to as_of: every holder with masked identity, shares and votes, share of capital and votes, share-number ranges, and whether they are on the board or VD (ABL 8:45); the classes with their förbehåll; open notes (aktiebrev, pant, nyttjanderätt); and a check against company_settings.antal_aktier.
Use when: You need who owns the company, how much, or the number range of someone's shares.
Don't use for: The dated history of entries (GET /share-register/events) or the board (GET /company-roles).
Pitfalls
- identity is masked; the full personnummer is never answered.
- reconciliation.status mismatch means the register and company_settings.antal_aktier disagree; ask the person which is right.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
as_of | string | no | The day the answer is for (YYYY-MM-DD). Default today. |
Response fields
| Name | Type | Description |
|---|---|---|
as_of | string | |
is_avstamningsbolag | boolean | The central securities depository keeps the aktiebok; this register takes no entries. |
total_shares | number | |
total_votes | number | |
next_free_share_number | number | Where the next issue starts. |
classes | object[] | |
holders | object[] | |
notes | object[] | |
reconciliation | object | |
incomplete | object | |
events_count | number |
Example response
{
"data": {
"as_of": "2026-10-29",
"total_shares": 1000,
"holders": [
{
"party_id": "9c1e…",
"name": "Anna Ek",
"shares": 1000,
"capital_pct": 100,
"votes_pct": 100
}
]
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/share-register/events
share-register.events.list · scope companies:read
List every aktiebok entry in entry order, each with a Swedish sentence and whether a rättelse voided it.
The dated history of the share register (ABL 5:9): bildande, emissions, transfers with reason and price, cancellations, conversions, splits, aktiebrev, pledges, usufruct, notes and corrections. Entries are never changed; a rattelse entry voids one.
Use when: You need when and how ownership changed, or the entry to correct.
Don't use for: Current holdings (GET /share-register).
Pitfalls
- An entry with voided true does not count; its correction is the later rattelse entry.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Response fields
| Name | Type | Description |
|---|---|---|
events[].share_register_event_id | string | |
events[].event_number | number | |
events[].event_date | string | |
events[].entered_at | string | |
events[].kind | "bildande" | "nyemission" | "fondemission" | "overlatelse" | "indragning" | "omvandling" | "split" | "sammanlaggning" | "aktiebrev" | "pant" | "nyttjanderatt" | "anteckning" | "rattelse" | |
events[].kind_label | string | |
events[].text | string | The entry as a Swedish sentence. |
events[].voided | boolean | A later rattelse entry voided this one. |
events[].corrects_event_id | string | null | |
events[].share_class_id | string | null | |
events[].from_party_id | string | null | |
events[].to_party_id | string | null | |
events[].counterparty_party_id | string | null | |
events[].range_start | number | null | |
events[].range_end | number | null | |
events[].transfer_reason | string | null | |
events[].price_total | number | null | |
events[].ratio | number | null | |
events[].aktiebrev_number | string | null | |
events[].aktiebrev_action | "issued" | "returned" | null | |
events[].note_status | "open" | "closed" | null | |
events[].registered_on | string | null | |
events[].decision_id | string | null | |
events[].document_id | string | null | |
events[].journal_entry_id | string | null | |
events[].note | string | null |
Example response
{
"data": {
"events": [
{
"share_register_event_id": "7a2b…",
"event_number": 1,
"event_date": "2020-01-10",
"kind": "bildande",
"text": "Bildande: aktie 1-1 000 (1 000 st, serie A) till Anna Ek",
"voided": false
}
]
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/beneficial-owners/assessments
beneficial-owners.confirm · scope companies:write
Record an assessment of the verkliga huvudmän (LRVH 2:1): who they are and why, or that there is none.
Keeps the dated record (basis, conclusion, family holdings checked, control agreements), brings the verklig_huvudman roles in line, and when the set changed adds a deadline to file the change with Bolagsverket without delay (LRVH 2:3). Dry-runnable.
Use when: After gnubok_get_beneficial_owners, once the person has confirmed the owners.
Don't use for: Filing with Bolagsverket: an authorised representative files in Bolagsverket's e-service.
Pitfalls
- A verklig huvudman is always a natural person: a company party is refused.
- owners must be empty for no_beneficial_owner and not empty for owners_identified.
Risk: medium · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
assessed_on | string | yes | The day of the investigation. |
conclusion | "owners_identified" | "no_beneficial_owner" | yes | |
owners | object[] | yes | |
basis | string | null | no | What the assessment rests on; default "Aktieboken per <date>". |
family_aggregation_checked | boolean | yes | Close family holdings were counted together (LRVH 1:5). |
family_note | string | null | no | |
control_agreements | boolean | yes | Control by agreement or board appointment rights exists (LRVH 1:3-4). |
control_note | string | null | no |
Response fields
| Name | Type |
|---|---|
beneficial_owner_assessment_id | string |
changed | boolean |
ended_role_ids | string[] |
added_role_ids | string[] |
deadline_source_key | string | null |
filing_url | string |
Example request
{
"assessed_on": "2026-10-29",
"conclusion": "owners_identified",
"owners": [
{
"party_id": "9c1e…"
}
],
"family_aggregation_checked": true,
"control_agreements": false
}
Example response
{
"data": {
"beneficial_owner_assessment_id": "3e7f…",
"changed": true,
"ended_role_ids": [],
"added_role_ids": [
"8d2a…"
],
"deadline_source_key": "bolaget:verklig-huvudman:3e7f…",
"filing_url": "https://bolagsverket.se/…"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/company-roles
company-roles.create · scope companies:write
Add a role from a date: board member, chair, suppleant, VD, vice VD, firmatecknare, revisor or contact person.
A role is end-dated, never deleted (POST /company-roles/{id}/end). The same person can hold several roles. A board change takes effect when Bolagsverket has the notice (ABL 8:13): registered_at records when. Dry-runnable.
Use when: The stämma elected a board member, the board appointed a VD, or a firmatecknare was added.
Don't use for: Verkliga huvudmän (POST /beneficial-owners/assessments records them with the LRVH 2:1 record).
Pitfalls
- COMPANY_ROLE_DUPLICATE: the person already holds that role.
- Filing the change with Bolagsverket is done at verksamt.se.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
party_id | string | null | no | The person, when already in the register. |
name | string | null | no | Or their name. |
kind | "person" | "company" | null | no | person (default) or company (a revisionsbolag). |
org_number | string | null | no | A company's org number. Never a personnummer. |
role | "styrelseledamot" | "styrelseordforande" | "styrelsesuppleant" | "vd" | "vice_vd" | "sarskild_firmatecknare" | "revisor" | "huvudansvarig_revisor" | "revisorssuppleant" | "kontaktperson" | yes | |
valid_from | string | yes | First day in the role. |
registered_at | string | null | no | When Bolagsverket registered it. |
decision_id | string | null | no |
Response fields
| Name | Type |
|---|---|
company_role_id | string |
party_id | string |
role | string |
valid_from | string | null |
Example request
{
"name": "Bo Ek",
"role": "styrelseledamot",
"valid_from": "2026-06-15"
}
Example response
{
"data": {
"company_role_id": "1f3c…",
"party_id": "9c1e…",
"role": "styrelseledamot",
"valid_from": "2026-06-15"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/company-roles/:id/end
company-roles.end · scope companies:write
End a role on a date (the last day in it). The row is kept.
An ended role cannot be ended again; the history stays for the records. Dry-runnable.
Use when: A board member left, a VD resigned, a revisor was replaced.
Don't use for: Removing a wrongly entered role: end it on its start date and add the right one.
Pitfalls
- COMPANY_ROLE_ALREADY_ENDED.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
valid_to | string | yes | Last day in the role. |
end_reason | string | null | no | Why the role ended, kept on the role (e.g. avgick på egen begäran). |
Response fields
| Name | Type |
|---|---|
company_role_id | string |
valid_to | string |
Example request
{
"valid_to": "2026-06-14"
}
Example response
{
"data": {
"company_role_id": "1f3c…",
"valid_to": "2026-06-14"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/corporate-meetings
corporate-meetings.create · scope companies:write
Plan a meeting: an årsstämma (prefilled from the årsredovisning and the roles), an extra stämma, a styrelsemöte or a per capsulam decision.
Creates a draft with its agenda. An årsstämma gets fastställande of the resultat- and balansräkning, the disposition and proposed dividend from the årsredovisning, ansvarsfrihet for the board and VD in office during the year, re-election of the board and revisor, and fees (ABL 7:11). A stämma gets the röstlängd from the aktiebok on the meeting day. Deadlines follow (kallelse, minutes within two weeks). Dry-runnable.
Use when: The company is to hold a stämma or a board meeting, or the owners decide per capsulam.
Don't use for: Recording a decision on an existing meeting (POST /corporate-meetings/{id}/decisions).
Pitfalls
- CORPORATE_MEETING_FISCAL_PERIOD_REQUIRED: an årsstämma needs fiscal_period_id.
- BOLAGET_PERSONNUMMER_IN_APP_ONLY: a personnummer was sent; name the person.
- A per capsulam stämma decision has no ABL rule; every shareholder signs it.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
kind | "arsstamma" | "extra_stamma" | "styrelsemote" | "per_capsulam" | yes | arsstamma, extra_stamma, styrelsemote or per_capsulam. |
organ | "bolagsstamma" | "styrelse" | null | no | per_capsulam only: bolagsstamma (all shareholders sign) or styrelse (all board members sign). |
meeting_date | string | yes | The meeting day (YYYY-MM-DD); may be in the future for a planned meeting. |
is_digital | boolean | null | no | |
use_template | boolean | null | no | Start from the agenda (default true). An årsstämma is prefilled from the årsredovisning and the roles. |
meeting_time | string | null | no | HH:MM. |
place | string | null | no | |
chair_party_id | string | null | no | Ordförande, when in the register (party_id from gnubok_list_company_roles or the share register). |
chair_name | string | null | no | Or the chair's name. |
secretary_party_id | string | null | no | Protokollförare. |
secretary_name | string | null | no | |
adjuster_party_ids | string[] | null | no | Justerare (replaces the list). |
adjuster_names | string[] | null | no | |
kallelse_date | string | null | no | The day the kallelse was sent. |
kallelse_method | string | null | no | How, e.g. "e-post till samtliga aktieägare". |
fiscal_period_id | string | null | no | Årsstämma: the fiscal year whose årsredovisning it adopts. |
notes | string | null | no |
Response fields
| Name | Type |
|---|---|
corporate_meeting_id | string |
kind | "arsstamma" | "extra_stamma" | "styrelsemote" | "per_capsulam" |
organ | "bolagsstamma" | "styrelse" |
meeting_date | string |
status | "draft" |
decisions_count | number |
Example request
{
"kind": "arsstamma",
"meeting_date": "2027-05-10",
"fiscal_period_id": "7c2a…",
"place": "Bolagets kontor"
}
Example response
{
"data": {
"corporate_meeting_id": "4b1e…",
"kind": "arsstamma",
"organ": "bolagsstamma",
"meeting_date": "2027-05-10",
"status": "draft",
"decisions_count": 15
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/corporate-meetings/:id/decisions
corporate-meetings.decisions.record · scope companies:write
Add or change a decision (paragraph) in a meeting's unsigned minutes, with its terms per kind.
Kinds: faststallande_rr_br, resultatdisposition, utdelning, ansvarsfrihet, val_styrelse, val_revisor, arvoden, andrad_bolagsordning, nyemission, fondemission, minskning, optioner, aterbetalning_villkorat_tillskott, ovrigt. The payload is validated per kind. An adopted election changes the roles when the minutes are signed; capital decisions are booked separately. Dry-runnable.
Use when: The stämma or the board decided something to record in the minutes.
Don't use for: Booking a dividend or an emission (a voucher), or registering shares (POST /share-register/events).
Pitfalls
- CORPORATE_DECISION_PAYLOAD_INVALID: the terms do not fit the kind; message names the fields.
- CORPORATE_MEETING_LOCKED: signed minutes never change.
- utdelning needs a payment_date (betalningsdag, ABL 18:3) before the minutes are signed; a warning says so.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
corporate_decision_id | string | null | no | Change this decision; omit to add one. |
item_number | number | null | no | The paragraph (§); a taken number moves the later ones down. Default: before the closing item. |
kind | "faststallande_rr_br" | "resultatdisposition" | "utdelning" | "ansvarsfrihet" | "val_styrelse" | "val_revisor" | "arvoden" | "andrad_bolagsordning" | "nyemission" | "fondemission" | "minskning" | "optioner" | "aterbetalning_villkorat_tillskott" | "ovrigt" | null | no | Required for a new decision. |
title | string | null | no | |
text | string | null | no | The decision as the minutes word it; null composes it from the payload. |
payload | object | null | no | Terms per kind, e.g. utdelning {amount_per_share, share_count, total_amount, payment_date}; val_styrelse {members:[{party_id|name, role}], term}; nyemission {share_count, price_per_share}. Names and party ids only. |
outcome | "bifallen" | "avslagen" | "bordlagd" | null | no | bifallen (default), avslagen or bordlagd. |
votes_for | number | null | no | Votes (röster) for, when it went to a vote. |
votes_against | number | null | no | |
votes_abstained | number | null | no | |
reservations | string | null | no | Reservation or dissent to note (ABL 8:24). |
Response fields
| Name | Type |
|---|---|
corporate_decision_id | string |
corporate_meeting_id | string |
item_number | number |
kind | "faststallande_rr_br" | "resultatdisposition" | "utdelning" | "ansvarsfrihet" | "val_styrelse" | "val_revisor" | "arvoden" | "andrad_bolagsordning" | "nyemission" | "fondemission" | "minskning" | "optioner" | "aterbetalning_villkorat_tillskott" | "ovrigt" |
Example request
{
"kind": "utdelning",
"payload": {
"amount_per_share": 50,
"share_count": 1000,
"total_amount": 50000,
"payment_date": "2027-05-31"
}
}
Example response
{
"data": {
"corporate_decision_id": "9f3d…",
"corporate_meeting_id": "4b1e…",
"item_number": 10,
"kind": "utdelning"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/corporate-meetings/:id/hold
corporate-meetings.hold · scope companies:write
Mark a meeting as held: a board meeting takes its minutes number, an årsstämma records its date on the årsredovisning.
Status draft to held, once the meeting day has come. Board minutes are numbered in sequence (ABL 8:26). An årsstämma that adopted the resultat- and balansräkning writes agm_date and the disposition outcome to the årsredovisning (the fastställelseintyg reads them). Deadlines follow: minutes available within two weeks (7:49), a Bolagsverket notice after a board change (8:44). The minutes stay open until signed in Accounted; elections change the roles then. Dry-runnable.
Use when: The meeting took place and its decisions are recorded.
Don't use for: Signing the minutes (a person, in Accounted).
Pitfalls
- CORPORATE_MEETING_IN_FUTURE: the meeting day has not come.
- CORPORATE_MEETING_ALREADY_HELD.
- A held meeting is never deleted.
Risk: medium · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Response fields
| Name | Type |
|---|---|
corporate_meeting_id | string |
status | "held" |
sequence_number | number | null |
agm_recorded | boolean |
Example response
{
"data": {
"corporate_meeting_id": "4b1e…",
"status": "held",
"sequence_number": null,
"agm_recorded": true
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/share-classes
share-classes.create · scope companies:write
Add a share class with its votes per share and the förbehåll of the bolagsordning.
A class (aktieslag, ABL 4:2) such as A or B. One class may carry at most ten times the votes of another (4:5): a larger ratio answers a warning. Dry-runnable.
Use when: The bolagsordning has more than one class, or förbehåll to note.
Don't use for: Issuing shares (POST /share-register/events).
Pitfalls
- SHARE_CLASS_DUPLICATE: the code exists.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
code | string | yes | Short code, e.g. A, B, Stam, Pref. |
name | string | null | no | |
votes_per_share | number | yes | Votes per share, e.g. 1 or 10 (or 0.1). |
forbehall_samtycke | boolean | no | Samtyckesförbehåll (ABL 4:8). |
forbehall_forkop | boolean | no | Förköpsförbehåll (ABL 4:18). |
forbehall_hembud | boolean | no | Hembudsförbehåll (ABL 4:27). |
forbehall_omvandling | boolean | no | Omvandlingsförbehåll (ABL 4:6). |
forbehall_inlosen | boolean | no | Inlösenförbehåll (ABL 20:31). |
forbehall_text | string | null | no | The clause as the bolagsordning words it. |
bolagsordning_reference | string | null | no | Where in the bolagsordning, e.g. § 9. |
Response fields
| Name | Type |
|---|---|
share_class_id | string |
code | string |
name | string | null |
votes_per_share | number |
forbehall_samtycke | boolean |
forbehall_forkop | boolean |
forbehall_hembud | boolean |
forbehall_omvandling | boolean |
forbehall_inlosen | boolean |
forbehall_text | string | null |
bolagsordning_reference | string | null |
Example request
{
"code": "B",
"votes_per_share": 1
}
Example response
{
"data": {
"id": "5d1c…",
"code": "B",
"votes_per_share": 1
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/share-register/events
share-register.events.create · scope companies:write
Add a dated entry to the aktiebok: an issue, a transfer, a cancellation, a conversion, a split, an aktiebrev, a pledge or a note.
Entries are kept forever (ABL 5:3) and numbered in sequence; a mistake is voided with kind rattelse and entered again. The register refuses an entry its history cannot hold: no share held twice, a transfer only of shares the transferor holds on that date. A new holder is named by to_name; their personnummer and address are completed in Accounted. Dry-runnable: the preview shows holdings before and after.
Use when: Shares were issued, sold, given, inherited, cancelled, split, pledged, or an aktiebrev was issued or returned.
Don't use for: Booking the money of an emission or a dividend (a voucher), or changing votes per share (PATCH /share-classes/{id}).
Pitfalls
- SHARE_REGISTER_NOT_HELD: the from-holder does not hold all of the shares on event_date.
- SHARE_REGISTER_RANGE_TAKEN: an issue overlaps shares already held; omit the range and send share_count.
- BOLAGET_PERSONNUMMER_IN_APP_ONLY: a personnummer was sent; name the person and complete them in the app.
- A transfer of a class with samtycke, förköp or hembud answers a warning until forbehall_cleared is true.
Risk: medium · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
kind | "bildande" | "nyemission" | "fondemission" | "overlatelse" | "indragning" | "omvandling" | "split" | "sammanlaggning" | "aktiebrev" | "pant" | "nyttjanderatt" | "anteckning" | "rattelse" | yes | bildande, nyemission, fondemission, overlatelse, indragning, omvandling, split, sammanlaggning, aktiebrev, pant, nyttjanderatt, anteckning or rattelse. |
event_date | string | yes | The day the change took effect (YYYY-MM-DD); never in the future. |
share_class_code | string | null | no | The class, e.g. A. Optional when the company has one class; the first issue creates class A. |
to_share_class_code | string | null | no | omvandling: the class the shares become. |
from_party_id | string | null | no | overlatelse, indragning, omvandling: the current holder (party_id from gnubok_get_share_register). |
to_party_id | string | null | no | Issues and overlatelse: the receiving party, when already in the register. |
to_name | string | null | no | Or the receiver's name, for a new holder. |
to_kind | "person" | "company" | null | no | person (default) or company. |
to_org_number | string | null | no | A company receiver's org number. Never a personnummer. |
range_start | number | null | no | First share number. |
range_end | number | null | no | Last share number. |
share_count | number | null | no | Instead of a range: issues take the next free numbers, transfers the holder's lowest block that fits. |
transfer_reason | "kop" | "gava" | "arv" | "testamente" | "bodelning" | "byte" | "apport" | "annat" | null | no | overlatelse: kop, gava, arv, testamente, bodelning, byte, apport or annat. |
price_total | number | null | no | Price or subscription amount in SEK, if any. |
ratio | number | null | no | split: each share becomes ratio; sammanlaggning: ratio shares become one. |
aktiebrev_number | string | null | no | aktiebrev: its number. |
aktiebrev_action | "issued" | "returned" | null | no | aktiebrev: issued, or returned (makulerat). |
counterparty_party_id | string | null | no | pant: the pledgee; nyttjanderatt: the holder of the right. |
counterparty_name | string | null | no | Or their name, when new. |
counterparty_kind | "person" | "company" | null | no | |
counterparty_org_number | string | null | no | |
note_status | "open" | "closed" | null | no | pant, nyttjanderatt: open or end the note. |
corrects_event_id | string | null | no | rattelse: the entry it voids. Enter the correct entry separately. |
registered_on | string | null | no | Emissions: the day Bolagsverket registered the decision. |
decision_id | string | null | no | |
document_id | string | null | no | The underlying document in the archive (avtal, protokoll). |
note | string | null | no | Free text; required for anteckning and rattelse (the reason). |
forbehall_cleared | boolean | null | no | overlatelse: the class's samtycke, förköp or hembud has been handled. |
Response fields
| Name | Type |
|---|---|
share_register_event_id | string |
event_number | number |
kind | "bildande" | "nyemission" | "fondemission" | "overlatelse" | "indragning" | "omvandling" | "split" | "sammanlaggning" | "aktiebrev" | "pant" | "nyttjanderatt" | "anteckning" | "rattelse" |
event_date | string |
range_start | number | null |
range_end | number | null |
share_class_id | string | null |
from_party_id | string | null |
to_party_id | string | null |
Example request
{
"kind": "overlatelse",
"event_date": "2026-10-01",
"from_party_id": "9c1e…",
"to_name": "Bo Ek",
"share_count": 100,
"transfer_reason": "gava"
}
Example response
{
"data": {
"share_register_event_id": "7a2b…",
"event_number": 4,
"kind": "overlatelse",
"event_date": "2026-10-01",
"range_start": 1,
"range_end": 100
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/signatory-rules
signatory-rules.set · scope companies:write
Set the firmateckning from a date; the rule in force ends the day before.
The registered text, e.g. "Firman tecknas av styrelsen. Firman tecknas av två ledamöter i förening." (ABL 8:35-37). Dry-runnable.
Use when: The board changed who signs for the company.
Don't use for: Adding a särskild firmatecknare as a person (POST /company-roles).
Pitfalls
- BOLAGET_DATES_INVALID: a rule already starts on or after valid_from.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required |
|---|---|---|
rule_text | string | yes |
valid_from | string | yes |
registered_at | string | null | no |
decision_id | string | null | no |
Response fields
| Name | Type |
|---|---|
signatory_rule_id | string |
rule_text | string |
valid_from | string |
ended_rule_ids | string[] |
Example request
{
"rule_text": "Firman tecknas av styrelsen",
"valid_from": "2026-06-15"
}
Example response
{
"data": {
"signatory_rule_id": "2b9d…",
"rule_text": "Firman tecknas av styrelsen",
"valid_from": "2026-06-15",
"ended_rule_ids": []
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
PATCH /api/v1/companies/:companyId/corporate-meetings/:id
corporate-meetings.update · scope companies:write
Change a meeting whose minutes are not signed: date, place, chair, protokollförare, justerare, kallelse, attendance or röstlängd presence.
Fields left out keep their value; null clears one. Moving the date takes the röstlängd from the aktiebok again. Signed minutes never change (CORPORATE_MEETING_LOCKED). Dry-runnable.
Use when: The kallelse was sent, the chair or justerare were chosen, or attendance is known.
Don't use for: Decisions (POST /corporate-meetings/{id}/decisions).
Pitfalls
- CORPORATE_MEETING_SIGNING_PENDING: the minutes are out for BankID signing.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
meeting_date | string | no | Moving the date takes the röstlängd from the aktiebok again. |
is_digital | boolean | no | |
meeting_time | string | null | no | HH:MM. |
place | string | null | no | |
chair_party_id | string | null | no | Ordförande, when in the register (party_id from gnubok_list_company_roles or the share register). |
chair_name | string | null | no | Or the chair's name. |
secretary_party_id | string | null | no | Protokollförare. |
secretary_name | string | null | no | |
adjuster_party_ids | string[] | null | no | Justerare (replaces the list). |
adjuster_names | string[] | null | no | |
kallelse_date | string | null | no | The day the kallelse was sent. |
kallelse_method | string | null | no | How, e.g. "e-post till samtliga aktieägare". |
fiscal_period_id | string | null | no | Årsstämma: the fiscal year whose årsredovisning it adopts. |
notes | string | null | no | |
presence | object[] | null | no | Röstlängd: who was present or represented. |
attendees | object[] | null | no | Others present (board, VD, revisor, guests); replaces the list. |
refresh_voting_list | boolean | null | no | Take the röstlängd from the aktiebok again. |
Response fields
| Name | Type |
|---|---|
corporate_meeting_id | string |
status | string |
Example request
{
"kallelse_date": "2027-04-08",
"kallelse_method": "e-post"
}
Example response
{
"data": {
"corporate_meeting_id": "4b1e…",
"status": "draft"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
PATCH /api/v1/companies/:companyId/share-classes/:id
share-classes.update · scope companies:write
Change a share class's name, votes per share or förbehåll; its code stays.
Votes per share decide the votes percent and so the verkliga huvudmän: change them only after the bolagsordning changed. Every change is kept in the audit log. Dry-runnable.
Use when: The bolagsordning was amended, or a förbehåll was missing.
Don't use for: Converting shares between classes (an omvandling entry).
Pitfalls
- SHARE_CLASS_NOT_FOUND: wrong share_class_id.
Risk: medium · Idempotent: yes · Reversible: yes · Dry-run supported: yes · Stage for approval: yes (?stage=true)
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. |
stage | string | no | true stages the write for approval instead of committing it: 202 with the pending operation to approve via POST /pending-operations/{id}/approve. Absent or false commits; other values are 400. A reason in the body (why you propose it, at most 500 characters) is shown to the approver as agent_reason and kept with the decision. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
name | string | null | no | |
votes_per_share | number | no | |
forbehall_samtycke | boolean | no | Samtyckesförbehåll (ABL 4:8). |
forbehall_forkop | boolean | no | Förköpsförbehåll (ABL 4:18). |
forbehall_hembud | boolean | no | Hembudsförbehåll (ABL 4:27). |
forbehall_omvandling | boolean | no | Omvandlingsförbehåll (ABL 4:6). |
forbehall_inlosen | boolean | no | Inlösenförbehåll (ABL 20:31). |
forbehall_text | string | null | no | The clause as the bolagsordning words it. |
bolagsordning_reference | string | null | no | Where in the bolagsordning, e.g. § 9. |
Response fields
| Name | Type |
|---|---|
share_class_id | string |
code | string |
name | string | null |
votes_per_share | number |
forbehall_samtycke | boolean |
forbehall_forkop | boolean |
forbehall_hembud | boolean |
forbehall_omvandling | boolean |
forbehall_inlosen | boolean |
forbehall_text | string | null |
bolagsordning_reference | string | null |
Example request
{
"share_class_id": "5d1c…",
"votes_per_share": 10
}
Example response
{
"data": {
"id": "5d1c…",
"code": "A",
"votes_per_share": 10
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}