The write contract¶
These are the rules that make Konto accept a create/update. The server validates them and rejects payloads that break them — getting these right is 90 % of a successful integration.
Sending write payloads¶
Create/update endpoints read the object from a data field. Send it as a
JSON-encoded string (universal, and what the official MCP/SDK uses):
{ "data": "{\"name\":\"Acme ehf\",\"kennitala\":\"1234567890\",\"email\":\"acme@example.is\",\"lang\":\"is\",\"currency\":\"ISK\"}" }
With a JSON body, data may also be the object itself ({"data":{…}}). Customer
endpoints additionally accept the fields flat at the top level. Costs and time
entries take top-level fields, not data. The
API reference documents the decoded object for each
endpoint.
Most creates and updates answer with result = the record's guid, not the
record itself. Fetch the record if you need its stored values.
Codes you'll need¶
VAT rate — tax¶
| Code | Rate | Use for |
|---|---|---|
S |
24 % | standard-rated goods & services |
AA |
11 % | reduced rate (books, food, accommodation…) |
Z |
0 % | zero-rated / exempt |
Warning
The API has no default VAT code or unit on item creation: send tax and
uom, or the item is refused. The MCP tool konto_create_item fills in Z
(0 %) and C62 when you leave them out, so through the MCP a forgotten tax
creates a zero-VAT item. Set S or AA explicitly for taxable items.
When you update an item, always send unit_price too: an update without
it sets the price to 0.
Unit of measure — uom¶
| Code | Unit | Code | Unit |
|---|---|---|---|
C62 |
pieces | KWH |
kWh |
HUR |
hours | MTK |
m² |
DAY |
days | MTQ |
m³ |
MIN |
minutes | TNE |
tonnes |
KGS |
kg | LTR |
litres |
MTR |
metres | KTM |
km |
Payment method — how_paid (costs)¶
1 = Account/bank transfer · 2 = Debit card · 3 = Credit card · 4 = Owner cash.
Invoice delivery — output_select (customers)¶
2 = e-invoice / XML (requires trading_partner_id) · 3 = email ·
4 = PDF (email optional).
Creating a customer ignores output_select: the customer gets email (3), or
e-invoice (2) when you send trading_partner_id. For PDF delivery, create the
customer and then update it with output_select: 4.
Cost code — type (costs)¶
A cost needs a numeric cost code; names such as Items are refused. The
API reference lists what each code means. Accepted codes:
3028 2173 3033 3085 3090 2093 2243 2193 2423 2443 2353 2383 2403
2263 3163 2333 3140 2283 2533 2633 3653 5028 2153 3080 9535
If you're unsure which to use, either ask Konto for the mapping, or upload the
receipt to POST /agent/costs and let Cost AI fill the code from the document.
Invoices¶
amountmust equal Σ(line items) + VAT, rounded to 2 decimals. The server rejects a mismatch — compute it from the exact items you send.- Dates — all three required:
issue_date(útgáfudagur) — today or earlier.due_date(gjalddagi) — must be ≤settlement_date.settlement_date(eindagi) — the last date before collection; ≥due_date.
type—invoiceorcredit. Required.- Line items are either an existing catalogue item (
guid+qty) or a free line withitem_number,description,qty,uom,taxandunit_price. Addadd_new: 1to also save a free line to the catalogue. - Every free line needs an
item_number— Konto's validation requires it even though the catalogue would auto-number. Supply one (any unique SKU string). - A catalogue line sent with your own
description,uom,unit_priceortaxupdates the catalogue item to those values. - Credit note:
type: credit+ref_invoice_guid— the original is marked credited and its customer is inherited. - Retries: send an
Idempotency-Keyheader, so a retried request cannot issue the invoice twice.
{
"amount": 24800,
"currency": "ISK",
"type": "invoice",
"customer": { "guid": "c1a2…" },
"issue_date": "2026-01-15",
"due_date": "2026-01-29",
"settlement_date": "2026-02-12",
"items": [
{ "add_new": 1, "description": "Consulting", "qty": 10,
"unit_price": 2000, "uom": "HUR", "tax": "S", "item_number": "10000001" }
]
}
10 × 2000 = 20 000 + 24 % VAT = 24 800 ✓
Customers¶
kennitala— 10 digits, no dash (e.g.1234567890); validated with a mod-11 checksum.email— required on create; optional later only whenoutput_select=4(PDF).lang(is/en) andcurrency(e.g.ISK) — required; there are no defaults.trading_partner_id(e-invoice recipient) — the recipient's bare kennitala. Do not prefix the Peppol scheme0196:— the API assumes it.- Create does not dedupe by kennitala — each
POSTmakes a new profile. To change an existing one, fetch it thenPUT.
Costs¶
- Keep
amountpositive even for a credit note — setcredit_note: 1to mark it; the server produces the credit document. vat_11/vat_24are amounts in ISK, not rates.supplier_idis the supplier's kennitala.
Accounting status (invoices & costs)¶
Updates change only the bookkeeping status, not the contents.
- Invoices: set any of
Created,Posted,Skipped,Error, with an optionalaccounting_message. - Costs: only a record in
Createdcan be updated, and only toPosted(terminal, locked),SkippedorError. To edit a Created cost's data, reopen it (move to New) first, then re-approve — that regenerates its bookkeeping XML.