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
Supplier payment files
Betalfil (pain.001) for supplier invoices: preview what can be paid, create a batch, download the file for the bank, cancel.
Endpoints
GET/api/v1/companies/:companyId/supplier-payment-batches: List supplier payment batches (betalfiler), newest first, with settlement progress.GET/api/v1/companies/:companyId/supplier-payment-batches/:id: Read one supplier payment batch (betalfil) with its lines and live settlement.GET/api/v1/companies/:companyId/supplier-payment-batches/:id/file: Download the payment file (pain.001, or the LB file for Svea Bank) of a supplier payment batch.POST/api/v1/companies/:companyId/supplier-payment-batches: Create a supplier payment file (betalfil: pain.001, or an LB file for Svea Bank) for one or more supplier invoices.POST/api/v1/companies/:companyId/supplier-payment-batches/:id/cancel: Cancel (makulera) a supplier payment batch.POST/api/v1/companies/:companyId/supplier-payment-batches/preview: Check which supplier invoices can go into a payment file (betalfil), with amounts, payees and warnings.
GET /api/v1/companies/:companyId/supplier-payment-batches
supplier-payment-batches.list · scope suppliers:read
List supplier payment batches (betalfiler), newest first, with settlement progress.
Returns the company's payment batches, newest first, cursor-paginated: status, total, item count, how many member invoices are settled (derived from the live invoices), download count and the member supplier_invoice_ids. Pass next_cursor from the answer as cursor to get the next page; it is null on the last page.
Use when: Checking which betalfiler exist, whether one has been downloaded, or which invoices are already in an active batch.
Don't use for: The lines of one batch (GET /supplier-payment-batches/{id}).
Pitfalls
- next_cursor rides in data (not meta): pass it back as ?cursor= until it is null.
- settled_count counts invoices with nothing left to pay, however they were settled; a created batch is not proof the bank executed it.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
status | "created" | "cancelled" | "all" | no | created (active), cancelled, or all (default). |
limit | number | no | Page size, 1-100 (default 50). |
cursor | string | no | next_cursor from the previous page. Omit for the first page. |
Response fields
| Name | Type |
|---|---|
supplier_payment_batches | object[] |
next_cursor | string | null |
Example response
{
"data": {
"supplier_payment_batches": [
{
"supplier_payment_batch_id": "5b0c…",
"format": "pain001",
"status": "created",
"currency": "SEK",
"total_amount": 12500,
"item_count": 2,
"settled_count": 0,
"msg_id": "ACCOUNTED-5566778899-B5B0C1A2F",
"file_generated_at": null,
"download_count": 0,
"created_at": "2026-09-25T09:00:00Z",
"cancelled_at": null,
"supplier_invoice_ids": [
"9e2f…",
"0a7d…"
]
}
],
"next_cursor": null
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/supplier-payment-batches/:id
supplier-payment-batches.get · scope suppliers:read
Read one supplier payment batch (betalfil) with its lines and live settlement.
Returns the batch, the company bank details it debits (as snapshotted at creation), and one line per invoice: amount, payment date, payee, reference, and the invoice's live status and remaining amount. file names the download filename, its content type and the v1 path that serves the file (available only while the batch is not cancelled).
Use when: Checking what a betalfil pays, or which of its invoices are settled.
Don't use for: Getting the file itself: GET /supplier-payment-batches/{id}/file.
Pitfalls
- The payee and amount per line are the snapshot the file pays, even if the supplier's details changed since.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Response fields
| Name | Type | Description |
|---|---|---|
supplier_payment_batch_id | string | |
handle | string (optional) | Typed handle of this supplier payment batch: spb_ plus its id as 32 lowercase hex. Accepted wherever the id is. |
format | "pain001" | "bg_lb" | pain001: ISO 20022 pain.001.001.03 XML. bg_lb: Bankgirot's LB file (80-character records, ISO 8859-1), for Svea Bank, which takes no pain.001. |
status | "created" | "cancelled" | |
currency | string | |
total_amount | number | |
item_count | number | |
settled_count | number | Member invoices with nothing left to pay, from the live invoices (paid via mark-paid or bank matching). |
msg_id | string | pain.001 MsgId, fixed at creation; the bank de-duplicates on it. An LB file carries no MsgId. |
file_generated_at | string | null | Last download of the file, or null if never downloaded. |
download_count | number | |
created_at | string | |
cancelled_at | string | null | |
supplier_invoice_ids | string[] | |
debtor | object | |
items | object[] | |
file | object |
Example response
{
"data": {
"supplier_payment_batch_id": "5b0c…",
"format": "pain001",
"status": "created",
"currency": "SEK",
"total_amount": 12500,
"item_count": 2,
"settled_count": 0,
"msg_id": "ACCOUNTED-5566778899-B5B0C1A2F",
"file_generated_at": null,
"download_count": 0,
"created_at": "2026-09-25T09:00:00Z",
"cancelled_at": null,
"supplier_invoice_ids": [
"9e2f…",
"0a7d…"
],
"debtor": {
"name": "Testbolaget AB",
"iban": "SE35 **** 0003",
"bic": "ESSESESS"
},
"items": [
{
"supplier_payment_batch_item_id": "71c4…",
"supplier_invoice_id": "9e2f…",
"supplier_invoice_number": "CD3014794407",
"arrival_number": 12,
"amount": 7500,
"payment_date": "2026-10-01",
"payee_name": "Derome Bygg AB",
"payee": {
"type": "bankgiro",
"label": "BG 5050-1055"
},
"reference": {
"type": "invoice_number",
"value": "CD3014794407"
},
"invoice_status": "approved",
"remaining_amount": 7500,
"settled": false
}
],
"file": {
"filename": "betalfil_20260925_5b0c1a2f.xml",
"content_type": "application/xml",
"available": true,
"download": "/api/v1/companies/{companyId}/supplier-payment-batches/{supplier_payment_batch_id}/file"
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
GET /api/v1/companies/:companyId/supplier-payment-batches/:id/file
supplier-payment-batches.file · scope suppliers:write
Download the payment file (pain.001, or the LB file for Svea Bank) of a supplier payment batch.
Returns the batch's payment file inline as content (a string), with filename, content_type, charset and sha256, in the same shape as the salary payment file: pain.001 XML written as UTF-8, or Bankgirot's LB file (format bg_lb, text/plain) written as ISO 8859-1. The file regenerates from the stored batch, so every download is byte-identical (same MsgId) and the bank's duplicate detection works. Each call records the download on the batch (file_generated_at, download_count). Upload the file in the bank's file channel, where the payments are signed; nothing is sent to the bank by this call and nothing is booked.
Use when: The batch is created and the user (or their payment operator) needs the file to upload in the bank.
Don't use for: Creating the batch (POST /supplier-payment-batches) or marking invoices paid (mark-paid after the bank executed).
Pitfalls
- Write
contenttofilenameincharset(UTF-8 for pain001, ISO 8859-1 for bg_lb with its CRLF line endings), exactly as returned; do not re-indent or re-encode the file. - A cancelled batch answers 409 SI_BATCH_CANCELLED: its file is never served again.
- Uploading the same file twice is caught by most banks through the MsgId, but not all: check download_count and the bank before re-uploading.
- Needs suppliers:write although it is a GET: the file is a payment instruction and the download is recorded.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Response fields
| Name | Type | Description |
|---|---|---|
supplier_payment_batch_id | string | |
format | "pain001" | "bg_lb" | pain001: ISO 20022 pain.001.001.03 XML. bg_lb: Bankgirot's LB file (80-character records, ISO 8859-1), for Svea Bank, which takes no pain.001. |
filename | string | |
content_type | "application/xml" | "text/plain" | |
charset | "utf-8" | "iso-8859-1" | How content becomes the bytes the bank takes. |
content | string | |
sha256 | string | Lowercase hex SHA-256 over the file bytes as encoded for the bank (UTF-8 for pain001, ISO 8859-1 for bg_lb). |
msg_id | string | |
item_count | number | |
total_amount | number | |
currency | string | |
download_count | number | Downloads including this one. |
Example response
{
"data": {
"supplier_payment_batch_id": "5b0c…",
"format": "pain001",
"filename": "betalfil_20260925_5b0c1a2f.xml",
"content_type": "application/xml",
"charset": "utf-8",
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pain.001.001.03\">…",
"sha256": "3f9a…",
"msg_id": "ACCOUNTED-5566778899-B5B0C1A2F",
"item_count": 2,
"total_amount": 12500,
"currency": "SEK",
"download_count": 1
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/supplier-payment-batches
supplier-payment-batches.create · scope suppliers:write
Create a supplier payment file (betalfil: pain.001, or an LB file for Svea Bank) for one or more supplier invoices.
Creates a payment batch: an immutable snapshot of one credit transfer per invoice (amount, payment date, the supplier's bankgiro / plusgiro / bank account, OCR or invoice-number reference) and the company's own bank details as debtor, with a pain.001 MsgId fixed at creation. The file takes the form the company's bank accepts (format: pain001, or bg_lb, Bankgirot's LB file, for Svea Bank, which takes no pain.001). Every invoice is re-read and re-checked inside one transaction, so an invoice settled or already batched meanwhile is refused. Books nothing and marks nothing paid. Download the file with GET /supplier-payment-batches/{id}/file and upload it in the bank, where the payments are signed; afterwards settle each invoice with mark-paid or bank matching. Idempotent. Dry-runnable.
Use when: The user wants to pay approved supplier invoices through their bank's file upload (typically the weekly or monthly payment run).
Don't use for: Marking invoices paid (POST /supplier-invoices/{id}/mark-paid), paying salaries (salary-runs/{id}/payment-file) or sending anything to the bank: this only produces the file.
Pitfalls
- Money leaves the company's account once the file is uploaded and signed in the bank: preview first (POST /supplier-payment-batches/preview) and check amounts and payees.
- An invoice already in an active batch answers 409 SI_BATCH_DUPLICATE_INVOICE with details.invoices; resend with confirm_already_batched true only when paying it twice is intended, otherwise cancel the old batch.
- Incomplete company bank details answer 400 SI_BATCH_DEBTOR_INCOMPLETE; details.missing is iban, bic, org_number, swedbank_ids, nordea_signer_id, nordea_agreement_id or bankgiro. iban and bic concern the paying account, the company's primary bank account (the one salaries are booked on), named in details.account: fill in its IBAN or BIC under Inställningar → Fakturor, Bankkonton för kundfakturor. The rest are company settings: swedbank_ids means a Swedbank company lacks swedbank_signer_id or swedbank_corporate_pay_id, nordea_signer_id that a Nordea company lacks its Signer ID, nordea_agreement_id that it has the Signer ID but lacks its CCM agreement id, bankgiro that a Svea Bank company lacks the bankgiro its LB file is sent from.
- An ineligible invoice fails the whole request with 400 SI_BATCH_INELIGIBLE_INVOICE and a reason per invoice; amount above the remaining amount answers 400 SI_BATCH_AMOUNT_EXCEEDS_REMAINING.
- A Swedbank company (swedbank_signer_id set, or swedbank_ids missing) can only pay bank accounts in a file: a bankgiro or plusgiro payee is ineligible with reason swedbank_iso2_giro_payee. A Svea Bank company's LB file pays bankgiro and plusgiro only: a bank-account payee is ineligible with reason lb_bank_account_payee. Leave those invoices out (the preview already does) and create the batch with the rest.
- A payment_date in the past is moved to today (banks reject passed execution dates). Only SEK invoices; at most 100 per batch.
- Between two requests (dry run, then create) a supplier's bank details can change: pass expected_payees from the dry run's items (payee.fingerprint, amount) and create answers 409 SI_BATCH_PAYEE_CHANGED instead of paying a changed account. A staged MCP create is pinned this way automatically.
Risk: high · 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 |
|---|---|---|---|
format | "pain001" | "bg_lb" | no | Deprecated and ignored: the company's bank decides the file form. pain001 (ISO 20022 pain.001.001.03) everywhere except Svea Bank, which takes only bg_lb (Bankgirot's LB file). The preview and create answers name it in format. |
items | object[] | yes | One line per supplier invoice, 1-100. |
confirm_already_batched | boolean | no | true includes invoices that already sit in another active batch (pays them twice if both files are uploaded). |
expected_payees | object[] | no | Optional lock: per invoice the payee fingerprint and amount a dry run showed. Create refuses with 409 SI_BATCH_PAYEE_CHANGED if either changed. Staging over MCP fills this in itself. |
Response fields
| Name | Type | Description |
|---|---|---|
supplier_payment_batch_id | string | |
handle | string (optional) | Typed handle of this supplier payment batch: spb_ plus its id as 32 lowercase hex. Accepted wherever the id is. |
msg_id | string | |
format | "pain001" | "bg_lb" | pain001: ISO 20022 pain.001.001.03 XML. bg_lb: Bankgirot's LB file (80-character records, ISO 8859-1), for Svea Bank, which takes no pain.001. |
status | "created" | |
currency | string | |
total_amount | number | |
item_count | number | |
created_at | string | |
file | object |
Example request
{
"items": [
{
"supplier_invoice_id": "9e2f…"
},
{
"supplier_invoice_id": "0a7d…",
"amount": 5000
}
]
}
Example response
{
"data": {
"supplier_payment_batch_id": "5b0c…",
"msg_id": "ACCOUNTED-5566778899-B5B0C1A2F",
"format": "pain001",
"status": "created",
"currency": "SEK",
"total_amount": 12500,
"item_count": 2,
"created_at": "2026-09-25T09:00:00Z",
"file": {
"filename": "betalfil_20260925_5b0c1a2f.xml",
"download": "/api/v1/companies/{companyId}/supplier-payment-batches/{supplier_payment_batch_id}/file"
}
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/supplier-payment-batches/:id/cancel
supplier-payment-batches.cancel · scope suppliers:write
Cancel (makulera) a supplier payment batch.
Marks an active batch cancelled: Accounted stops serving its file and its invoices can go into a new batch. The batch and its lines are kept (they are underlag for the payment instruction). A file already uploaded to the bank is NOT recalled: stop those payments in the bank. Cannot be undone; create a new batch instead. Idempotent. Dry-runnable.
Use when: A betalfil was created by mistake or with wrong amounts, before (or instead of) uploading it.
Don't use for: Stopping a payment the bank already has (do that in the bank) or un-paying an invoice.
Pitfalls
- An already cancelled batch answers 409 SI_BATCH_ALREADY_CANCELLED.
- download_count above 0 means the file may already be at the bank: check there too.
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 |
|---|---|
supplier_payment_batch_id | string |
status | "cancelled" |
cancelled_at | string | null |
Example response
{
"data": {
"supplier_payment_batch_id": "5b0c…",
"status": "cancelled",
"cancelled_at": "2026-09-25T10:00:00Z"
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}
POST /api/v1/companies/:companyId/supplier-payment-batches/preview
supplier-payment-batches.preview · scope suppliers:read
Check which supplier invoices can go into a payment file (betalfil), with amounts, payees and warnings.
Evaluates the given supplier invoices exactly as create will: eligible lines with the default amount (the remaining amount), payment date (the due date, the banking day before it when it falls on a weekend or holiday, or today when that has passed), payee (bankgiro, plusgiro or bank account from the supplier) and reference (OCR when valid, else the invoice number), plus non-blocking warnings; excluded invoices with the reason; the file form the company's bank takes (format: pain001, or bg_lb for Svea Bank); and whether the company's own bank details are complete. The file pays from the company's primary bank account, the account salaries are booked on, with that account's IBAN and BIC; org number, and the bankgiro an LB file is sent from, come from company settings. Reads only; creates nothing.
Use when: Before creating a payment batch, to see what would be paid and what blocks it.
Don't use for: Creating the batch (POST /supplier-payment-batches) or listing unpaid supplier invoices (GET /supplier-invoices).
Pitfalls
- Excluded reasons: not_payable (draft, paid, credited...), nothing_remaining, credit_note, foreign_currency (only SEK), payee_missing / payee_invalid (fix the supplier's bankgiro, plusgiro or clearing + account number), reference_missing (no valid OCR and no supplier invoice number: add one of them to the invoice), payee_unconfirmed / payee_rejected (the invoice states bank details the supplier card lacks and a person has not approved them, or rejected them: a person decides in Accounted under Att göra; gnubok_confirm_supplier_payee stages the approval), attest_required (the attest policy of the company requires attest for the invoice and it has not been given: an attester approves it first), not_found, in_bank_payment, swedbank_iso2_giro_payee (the company pays through Swedbank, whose ISO 2.0 file agreement pays to bank accounts only: a supplier with a bankgiro or plusgiro is left out; pay those invoices with a bank payment or in the internet bank), lb_bank_account_payee (the company's bank takes only an LB file, which here pays to bankgiro and plusgiro only: a supplier paid to a bank account is left out; pay it in the internet bank).
- debtor_ok false means create will refuse with SI_BATCH_DEBTOR_INCOMPLETE: debtor_missing names what to fill in (iban or bic: the paying account, named in debtor_account, has no IBAN or its bank cannot be determined; fill it in on that account under Inställningar → Fakturor, Bankkonton för kundfakturor, or make another account primary under Inställningar → Bokföring. org_number, swedbank_ids: a Swedbank company's swedbank_signer_id and swedbank_corporate_pay_id, which Swedbank assigns and refuses a file without, nordea_signer_id and nordea_agreement_id: a Nordea company's Signer ID and CCM agreement id, which Nordea assigns and refuses a file without (nordea_signer_id is named while the Signer ID is missing, nordea_agreement_id when only the agreement id is), or bankgiro: the company's bankgiro, which an LB file is sent from).
- already_batched is a warning here but a refusal at create unless confirm_already_batched is true: paying the same invoice twice is the risk.
- Only SEK invoices; at most 100 per call.
Risk: low · Idempotent: yes · Reversible: no · Dry-run supported: no
Request body
| Name | Type | Required | Description |
|---|---|---|---|
format | "pain001" | "bg_lb" | no | Deprecated and ignored: the company's bank decides the file form. pain001 (ISO 20022 pain.001.001.03) everywhere except Svea Bank, which takes only bg_lb (Bankgirot's LB file). The preview and create answers name it in format. |
supplier_invoice_ids | string[] | yes | The supplier invoices to evaluate (supplier_invoice_id), 1-100. |
Response fields
| Name | Type | Description |
|---|---|---|
eligible | object[] | |
excluded | object[] | |
format | "pain001" | "bg_lb" | The file form the company's bank takes, which create will write. |
total_amount | number | |
currency | "SEK" | |
debtor_ok | boolean | |
debtor_missing | "iban" | "bic" | "org_number" | "swedbank_ids" | "nordea_signer_id" | "nordea_agreement_id" | "bankgiro" | null | |
debtor_account | object | null | With debtor_missing iban or bic: the paying account that lacks it. Null otherwise. |
Example request
{
"supplier_invoice_ids": [
"9e2f…"
]
}
Example response
{
"data": {
"eligible": [
{
"supplier_invoice_id": "9e2f…",
"supplier_name": "Derome Bygg AB",
"supplier_invoice_number": "CD3014794407",
"amount": 737.5,
"payment_date": "2026-10-01",
"payee": {
"type": "bankgiro",
"label": "BG 5050-1055"
},
"reference": {
"type": "invoice_number",
"value": "CD3014794407"
},
"warnings": [
"payee_city_missing"
],
"active_supplier_payment_batch_id": null
}
],
"excluded": [],
"format": "pain001",
"total_amount": 737.5,
"currency": "SEK",
"debtor_ok": true,
"debtor_missing": null,
"debtor_account": null
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}