Download OpenAPI specification:
OAuth2 agent surface for Konto — customers, items, invoices, costs, tasks and product sales.
The Agent API lets a third-party application act on behalf of a Konto user, after that user signs in and consents to a set of scopes. It is the OAuth2 surface behind the Konto MCP connector and is the recommended path for user-delegated and AI integrations.
For headless server-to-server integrations (no user to log in) — e.g. a billing cron or an ERP sync running as a service — use the legacy
username+api_keyREST API instead (see the in-app reference).
| Host | Purpose | |
|---|---|---|
| Production | https://konto.is |
Real accounts, real invoices & email. |
| Development | https://dev.konto.is |
Safe sandbox. Sign in with a dev/test account. |
OAuth clients are per-environment: a client_id registered on dev does
not exist on prod, and vice versa. The OAuth endpoints live under
/strax/agent/*; the resource endpoints under /api/v1/agent/*.
dev.konto.is is always in maintenance mode. Server-side calls to dev must append
?en4_maint_code=<code>or receive HTTP 503. Ask Konto for the current dev bypass code. Never send it to production.
Every resource endpoint returns a JSON envelope:
{ "status": true, "message": "", "result": { ... } }
status is a boolean. On a handled error the HTTP status may still be 200
with status: false and a message — always check status, not just the
HTTP code. (Auth/scope/method failures do use real 4xx codes — see Errors.)
Create/update endpoints read the resource object from a data field. Send
it as a JSON-encoded string — this is the universally-supported form and
the one the official MCP/SDK uses:
{ "data": "{\"name\":\"Acme ehf\",\"kennitala\":\"1234567890\",\"email\":\"acme@example.is\"}" }
Customer endpoints additionally accept the object nested ({"data":{...}}) or
the fields flat at the top level. The schemas below document the decoded
object shape in each data field.
tax): S = 24 %, AA = 11 %, Z = 0 %.uom): C62 pieces · HUR hours · DAY days ·
KGS kg · MTR m · LTR l · MTK m² · MTQ m³ · TNE t · KWH kWh ·
MIN minutes · KTM km.amount must equal Σ(line items) + VAT, rounded to 2 dp — the
server rejects a mismatch.issue_date ≤ due_date ≤ settlement_date.
settlement_date (eindagi) is required.add_new: 1) requires an item_number.kennitala: 10 digits, no dash; validated (mod-11 checksum).trading_partner_id (e-invoice): the recipient's bare kennitala —
do not prefix the Peppol scheme 0196:.how_paid: 1 Account · 2 Debit · 3 Credit · 4 Owner cash.output_select (delivery): 2 e-invoice/XML (needs
trading_partner_id) · 3 email · 4 PDF.Exchange an authorization code (with grant_type=authorization_code) or
a refresh_token (with grant_type=refresh_token) for an access token.
Refresh tokens rotate — persist the new refresh_token from every
response. Refresh does not require redirect_uri.
| client_id required | string |
| client_secret | string Required for confidential clients. |
| grant_type required | string Enum: "authorization_code" "refresh_token" |
| code | string Required when grant_type=authorization_code. |
| redirect_uri | string <uri> Required (and exact-match) when exchanging a code. |
| code_verifier | string PKCE verifier, if a challenge was sent. |
| refresh_token | string Required when grant_type=refresh_token. |
{- "client_id": "string",
- "client_secret": "string",
- "grant_type": "authorization_code",
- "code": "string",
- "code_verifier": "string",
- "refresh_token": "string"
}{- "access_token": "string",
- "refresh_token": "string",
- "expires_in": 0,
- "scope": "string"
}Create an agent client and receive a client_id + client_secret
(the secret is shown once). In practice Konto often provisions
clients — especially shared app clients (one client many merchants
authorize) — manually; contact Konto for onboarding.
| name required | string |
| description | string |
| redirect_uri required | string <uri> Exact-match at authorize time. |
{- "name": "string",
- "description": "string",
}{- "client_id": "string",
- "client_secret": "string"
}Returns the connected company name, registration number (kennitala) and username. The MCP also derives the environment from the host.
{- "status": true,
- "message": "string",
- "result": {
- "company_name": "string",
- "registration_no": "string",
- "username": "string"
}
}Immediately invalidates that client's tokens. Irreversible. Revoking the client you are currently using cuts off your own access.
| id required | string The agent client_id to revoke. |
{- "status": true,
- "message": "string",
- "result": null
}Search matches name, kennitala or email. Note: results include deactivated profiles — filter client-side if needed. To look up by kennitala exactly, use ?kennitala=<kt>.
| search | string |
| kennitala | string Exact kennitala lookup. |
| limit | integer Default: 10 Results per page (default 10). |
| page | integer Default: 1 Page number (default 1). |
{- "status": true,
- "message": "string",
- "result": null
}Does not dedupe by kennitala — each call creates a new profile. To change an existing one, GET it then PUT. Returns the created customer incl. its guid.
The customer object, as a JSON-encoded data string (also accepts a nested object or flat top-level fields).
required | string or CustomerCreate (object) |
{- "name": "Acme ehf",
- "kennitala": "1234567890",
- "email": "acme@example.is",
- "output_select": "3"
}{- "status": true,
- "message": "string",
- "result": null
}Send the fields you want to change. GET first if you need to preserve existing values. PUT bodies must be application/json.
| guid required | string The resource's GUID. |
The customer object, as a JSON-encoded data string (also accepts a nested object or flat top-level fields).
required | string or CustomerCreate (object) |
{- "name": "Acme ehf",
- "kennitala": "1234567890",
- "email": "acme@example.is",
- "output_select": "3"
}{- "status": true,
- "message": "string",
- "result": null
}Catalogue product/service. tax defaults to Z (0 %) if omitted — set S or AA for taxable items.
required | string or ItemCreate (object) |
{- "data": "string"
}{- "status": true,
- "message": "string",
- "result": null
}| guid required | string The resource's GUID. |
required | string or ItemCreate (object) |
{- "data": "string"
}{- "status": true,
- "message": "string",
- "result": null
}| limit | integer Default: 10 Results per page (default 10). |
| page | integer Default: 1 Page number (default 1). |
| accounting_status | string Enum: "Created" "Posted" "Skipped" "Error" |
| from_date | string <date> Start date (YYYY-MM-DD). |
| to_date | string <date> End date (YYYY-MM-DD). |
{- "status": true,
- "message": "string",
- "result": null
}Creates and issues an invoice — Konto delivers it to the customer per
their delivery setting. amount must equal Σ(line items) + VAT.
For a credit note, send type: credit + ref_invoice_guid (the original
is marked credited and its customer is inherited).
required | string or InvoiceCreate (object) JSON-encoded InvoiceCreate object (stringify before sending). |
{- "data": "{\"amount\":24800,\"currency\":\"ISK\",\"customer\":{\"guid\":\"c1a2…\"},\"issue_date\":\"2026-07-13\",\"due_date\":\"2026-07-27\",\"settlement_date\":\"2026-08-10\",\"type\":\"invoice\",\"items\":[{\"add_new\":1,\"description\":\"Consulting\",\"qty\":10,\"unit_price\":2000,\"uom\":\"HUR\",\"tax\":\"S\",\"item_number\":\"10000001\"}]}"
}{- "status": true,
- "message": "string",
- "result": null
}Updates only the bookkeeping accounting status (and an optional message). It cannot edit amounts, dates, line items or the customer.
| guid required | string The resource's GUID. |
| data | string JSON-encoded |
{- "data": "string"
}{- "status": true,
- "message": "string",
- "result": null
}A template that auto-generates invoices on a schedule. Same amount/line-item and date rules as a normal invoice.
required | string or RecurringInvoiceCreate (object) JSON-encoded RecurringInvoiceCreate object. |
{- "data": "string"
}{- "status": true,
- "message": "string",
- "result": null
}Records return oldest-first — pass from_date for "recent" queries. Heavy file/xml fields are omitted from lists; fetch a single cost for them.
| limit | integer Default: 10 Results per page (default 10). |
| page | integer Default: 1 Page number (default 1). |
| accounting_status | string Comma-separated statuses. |
| type | string cost_code filter (numeric). |
| supplier_id | string |
| date_filter | string Default: "date" Enum: "created_date" "date" |
| from_date | string <date> Start date (YYYY-MM-DD). |
| to_date | string <date> End date (YYYY-MM-DD). |
{- "status": true,
- "message": "string",
- "result": null
}Upload a receipt/invoice image or PDF (multipart/form-data, max 5 MB)
for Konto's AI to extract amount, supplier, VAT and cost code. When Cost
AI is enabled the record is queued (result.queue = true) — re-fetch the
cost to read extracted fields. If you already have the numbers, use
/costs/advanced instead.
| date required | string <date> |
| description | string |
| file required | string <binary> jpg, jpeg, png, gif or pdf; ≤ 5 MB. |
{- "status": true,
- "message": "string",
- "result": null
}Record a cost from numbers you already have. File attachment optional. For a credit note set credit_note: 1 and keep amount positive.
| date required | string <date> |
| amount required | number |
| how_paid required | integer Enum: 1 2 3 4 1=Account, 2=Debit, 3=Credit, 4=Owner cash. |
| supplier_name required | string |
| supplier_id required | string Supplier kennitala / ID. |
| type required | string Numeric cost code (e.g. 2353). |
| description | string |
| vat_11 | number VAT amount (ISK) in the 11% bracket — an amount, not a rate. |
| vat_24 | number VAT amount (ISK) in the 24% bracket. |
| credit_note | integer 1 to record as a credit note; keep amount positive. |
{- "date": "2019-08-24",
- "amount": 0,
- "how_paid": 1,
- "supplier_name": "string",
- "supplier_id": "string",
- "type": "string",
- "description": "string",
- "vat_11": 0,
- "vat_24": 0,
- "credit_note": 0
}{- "status": true,
- "message": "string",
- "result": null
}| accounting_status | string |
| type | string |
| supplier_id | string |
| from_date | string <date> Start date (YYYY-MM-DD). |
| to_date | string <date> End date (YYYY-MM-DD). |
{- "status": true,
- "message": "string",
- "result": {
- "count": 0
}
}Updates only the accounting status (Created/Posted/Skipped/Error) + optional message. Posted is terminal. To edit a Created cost's data, move it to New first, then re-approve.
| guid required | string The resource's GUID. |
| data | string JSON-encoded |
{- "data": "string"
}{- "status": true,
- "message": "string",
- "result": null
}Permanent and irreversible. Prefer status Skipped to exclude from bookkeeping. Posted costs cannot be deleted.
| guid required | string The resource's GUID. |
{- "status": true,
- "message": "string",
- "result": null
}Moves an approved (Created), non-Posted cost back to New so it can be edited; re-approving regenerates its bookkeeping XML.
| guid required | string The resource's GUID. |
{- "status": true,
- "message": "string",
- "result": null
}| type | string Default: "open" Enum: "open" "invoice" "older" |
| limit | integer Default: 10 Results per page (default 10). |
| page | integer Default: 1 Page number (default 1). |
{- "status": true,
- "message": "string",
- "result": null
}A task linked to a customer, with an associated (existing or inline) item.
required | string or TaskCreate (object) JSON-encoded TaskCreate object. |
{- "data": "string"
}{- "status": true,
- "message": "string",
- "result": null
}Each log entry carries the task-LOG guid needed by the log edit/delete endpoints.
| guid required | string The resource's GUID. |
{- "status": true,
- "message": "string",
- "result": null
}Stops the running timer. Send adv: 1 with date/h/p to record a specific dated time entry instead.
| guid required | string The resource's GUID. |
| description | string |
| adv | string
|
| date | string <date> |
| end_date | string <date> |
| h | string Hours as a decimal string, e.g. "1.5". |
| p | string Optional unit-price override (ISK). |
{- "description": "string",
- "adv": "string",
- "date": "2019-08-24",
- "end_date": "2019-08-24",
- "h": "string",
- "p": "string"
}{- "status": true,
- "message": "string",
- "result": null
}Takes the task-LOG entry's guid (from a task's log list), not the task's guid.
| guid required | string Task-LOG entry guid. |
| description | string |
| date | string <date> |
| end_date | string <date> |
| h | string |
| p | string |
{- "guid": "string",
- "description": "string",
- "date": "2019-08-24",
- "end_date": "2019-08-24",
- "h": "string",
- "p": "string"
}{- "status": true,
- "message": "string",
- "result": null
}Read-only. Each result has a sale type: STAND, SUB, DONA, EVENT. Only EVENT sales have attendees.
| search_text | string |
| limit | integer Default: 10 Results per page (default 10). |
| page | integer Default: 1 Page number (default 1). |
{- "status": true,
- "message": "string",
- "result": null
}The guid must belong to an EVENT-type sale.
| guid required | string The resource's GUID. |
| limit | integer Default: 10 Results per page (default 10). |
| page | integer Default: 1 Page number (default 1). |
{- "status": true,
- "message": "string",
- "result": null
}