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
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 pain.001 payment file of a supplier payment batch.POST/api/v1/companies/:companyId/supplier-payment-batches: Create a supplier payment file (betalfil, pain.001) 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 and the v1 path that serves the XML (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 XML 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 | |
format | "pain001" | |
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. |
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 pain.001 payment file of a supplier payment batch.
Returns the batch's XML payment file inline as content (a UTF-8 string), with filename, content_type and sha256, in the same shape as the salary payment file. 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
contenttofilenameas UTF-8, exactly as returned; do not re-indent or re-encode the XML. - 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" | |
filename | string | |
content_type | "application/xml" | |
content | string | |
sha256 | string | Lowercase hex SHA-256 over the UTF-8 file bytes. |
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",
"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) 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. 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 XML 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 or org_number (company settings).
- 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 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
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 |
|---|---|---|---|
format | "pain001" | no | File format. pain001 (ISO 20022 pain.001.001.03, accepted by every Swedish bank) is the only one. |
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 |
|---|---|
supplier_payment_batch_id | string |
msg_id | string |
format | "pain001" |
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
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. |
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, or today when it 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; and whether the company's own bank details (IBAN, BIC, org number: the pain.001 debtor) are complete. 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), not_found.
- debtor_ok false means create will refuse with SI_BATCH_DEBTOR_INCOMPLETE: debtor_missing names the company setting to fill in (iban, bic or org_number).
- 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" | no | File format. pain001 (ISO 20022 pain.001.001.03, accepted by every Swedish bank) is the only one. |
supplier_invoice_ids | string[] | yes | The supplier invoices to evaluate (supplier_invoice_id), 1-100. |
Response fields
| Name | Type |
|---|---|
eligible | object[] |
excluded | object[] |
total_amount | number |
currency | "SEK" |
debtor_ok | boolean |
debtor_missing | "iban" | "bic" | "org_number" | null |
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": [],
"total_amount": 737.5,
"currency": "SEK",
"debtor_ok": true,
"debtor_missing": null
},
"meta": {
"request_id": "req_…",
"api_version": "2026-05-12"
}
}