Konto Agent API (1.0.0)

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_key REST API instead (see the in-app reference).

Environments

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.

Response envelope

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 messagealways check status, not just the HTTP code. (Auth/scope/method failures do use real 4xx codes — see Errors.)

Sending write payloads

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.

The write contract (read before creating anything)

  • VAT code (tax): S = 24 %, AA = 11 %, Z = 0 %.
  • Unit of measure (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.
  • Invoice amount must equal Σ(line items) + VAT, rounded to 2 dp — the server rejects a mismatch.
  • Invoice date chain: issue_date ≤ due_date ≤ settlement_date. settlement_date (eindagi) is required.
  • New inline invoice line (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:.
  • Cost how_paid: 1 Account · 2 Debit · 3 Credit · 4 Owner cash.
  • Customer output_select (delivery): 2 e-invoice/XML (needs trading_partner_id) · 3 email · 4 PDF.

Authentication

OAuth2 authorization-code flow with PKCE. Endpoints live under /strax/agent.

Consent screen (start the OAuth flow)

Send the user's browser here. They sign in to Konto, review the requested scopes, and are redirected back to redirect_uri with a short-lived authorization code (10-minute TTL) and your state.

PKCE: if you send a code_challenge, only S256 is accepted. Public clients (no client_secret) must send one. redirect_uri must match the value registered for the client exactly.

query Parameters
client_id
required
string
scope
required
string

Comma-separated scopes (e.g. nav,create_invoice,cost).

redirect_uri
required
string <uri>
state
required
string
code_challenge
string
code_challenge_method
string
Value: "S256"

Responses

Exchange a code or refresh token for tokens

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.

Request Body schema: application/json
required
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.

Responses

Request samples

Content type
application/json
{
  • "client_id": "string",
  • "client_secret": "string",
  • "grant_type": "authorization_code",
  • "code": "string",
  • "redirect_uri": "http://example.com",
  • "code_verifier": "string",
  • "refresh_token": "string"
}

Response samples

Content type
application/json
{
  • "access_token": "string",
  • "refresh_token": "string",
  • "expires_in": 0,
  • "scope": "string"
}

Register an agent client

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.

Request Body schema: application/json
required
name
required
string
description
string
redirect_uri
required
string <uri>

Exact-match at authorize time.

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "client_id": "string",
  • "client_secret": "string"
}

Account & agents

Identity, and managing which agent clients have access.

Account identity / health check

Returns the connected company name, registration number (kennitala) and username. The MCP also derives the environment from the host.

Authorizations:
kontoOAuth

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": {
    }
}

List authorized agent clients

The agent clients currently authorized on this account, with granted scopes and timestamps.

Authorizations:
kontoOAuth

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Revoke an agent client

Immediately invalidates that client's tokens. Irreversible. Revoking the client you are currently using cuts off your own access.

Authorizations:
kontoOAuth
path Parameters
id
required
string

The agent client_id to revoke.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Agent audit log

Recent actions taken by agent clients on this account. See the in-app reference for the record shape.

Authorizations:
kontoOAuth

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Customers

Scope: manage_customers.

List / search customers

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>.

Authorizations:
kontoOAuth
query Parameters
search
string
kennitala
string

Exact kennitala lookup.

limit
integer
Default: 10

Results per page (default 10).

page
integer
Default: 1

Page number (default 1).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create a customer

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.

Authorizations:
kontoOAuth
Request Body schema: application/json
required

The customer object, as a JSON-encoded data string (also accepts a nested object or flat top-level fields).

One of
required
string or CustomerCreate (object)

Responses

Request samples

Content type
application/json
Example
{
  • "name": "Acme ehf",
  • "kennitala": "1234567890",
  • "email": "acme@example.is",
  • "output_select": "3"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Count customers

Authorizations:
kontoOAuth
query Parameters
search
string

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": {
    }
}

Get a customer

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Update a customer

Send the fields you want to change. GET first if you need to preserve existing values. PUT bodies must be application/json.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Request Body schema: application/json
required

The customer object, as a JSON-encoded data string (also accepts a nested object or flat top-level fields).

One of
required
string or CustomerCreate (object)

Responses

Request samples

Content type
application/json
Example
{
  • "name": "Acme ehf",
  • "kennitala": "1234567890",
  • "email": "acme@example.is",
  • "output_select": "3"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Items

Product/service catalogue. Scope: nav.

List items

Authorizations:
kontoOAuth
query Parameters
limit
integer
Default: 10

Results per page (default 10).

page
integer
Default: 1

Page number (default 1).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create an item

Catalogue product/service. tax defaults to Z (0 %) if omitted — set S or AA for taxable items.

Authorizations:
kontoOAuth
Request Body schema: application/json
required
required
string or ItemCreate (object)

Responses

Request samples

Content type
application/json
{
  • "data": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Count items

Authorizations:
kontoOAuth

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": {
    }
}

Get an item

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Update an item

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Request Body schema: application/json
required
required
string or ItemCreate (object)

Responses

Request samples

Content type
application/json
{
  • "data": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Invoices

Scopes: nav (read/update), create_invoice (create), recurring.

List invoices

Authorizations:
kontoOAuth
query Parameters
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).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create an invoice (or credit note)

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).

Authorizations:
kontoOAuth
Request Body schema: application/json
required
required
string or InvoiceCreate (object)

JSON-encoded InvoiceCreate object (stringify before sending).

Responses

Request samples

Content type
application/json
{
  • "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\"}]}"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Get an invoice

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Update invoice accounting status

Updates only the bookkeeping accounting status (and an optional message). It cannot edit amounts, dates, line items or the customer.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Request Body schema: application/json
required
data
string

JSON-encoded { "accounting_status": "...", "accounting_message": "..." }.

Responses

Request samples

Content type
application/json
{
  • "data": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create a recurring invoice

A template that auto-generates invoices on a schedule. Same amount/line-item and date rules as a normal invoice.

Authorizations:
kontoOAuth
Request Body schema: application/json
required
required
string or RecurringInvoiceCreate (object)

JSON-encoded RecurringInvoiceCreate object.

Responses

Request samples

Content type
application/json
{
  • "data": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Costs

Expenses / receipts. Scope: cost.

List costs

Records return oldest-first — pass from_date for "recent" queries. Heavy file/xml fields are omitted from lists; fetch a single cost for them.

Authorizations:
kontoOAuth
query Parameters
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). Items = 2353.

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).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create a cost from a receipt file (OCR)

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.

Authorizations:
kontoOAuth
Request Body schema: multipart/form-data
required
date
required
string <date>
description
string
file
required
string <binary>

jpg, jpeg, png, gif or pdf; ≤ 5 MB.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create a cost from structured fields

Record a cost from numbers you already have. File attachment optional. For a credit note set credit_note: 1 and keep amount positive.

Authorizations:
kontoOAuth
Request Body schema: application/json
required
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). Items = 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.

Responses

Request samples

Content type
application/json
{
  • "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
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Count costs

Authorizations:
kontoOAuth
query Parameters
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).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": {
    }
}

Get a cost (with file & xml)

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Update cost accounting status

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.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Request Body schema: application/json
required
data
string

JSON-encoded { "accounting_status": "...", "accounting_message": "..." }.

Responses

Request samples

Content type
application/json
{
  • "data": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Delete a cost

Permanent and irreversible. Prefer status Skipped to exclude from bookkeeping. Posted costs cannot be deleted.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Re-open a cost (move back to New)

Moves an approved (Created), non-Posted cost back to New so it can be edited; re-approving regenerates its bookkeeping XML.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Tasks

Tasks & time tracking. Scope: task.

List tasks

Authorizations:
kontoOAuth
query Parameters
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).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Create a task

A task linked to a customer, with an associated (existing or inline) item.

Authorizations:
kontoOAuth
Request Body schema: application/json
required
required
string or TaskCreate (object)

JSON-encoded TaskCreate object.

Responses

Request samples

Content type
application/json
{
  • "data": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Count tasks

Authorizations:
kontoOAuth
query Parameters
type
string
Default: "open"
Enum: "open" "invoice" "older"

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": {
    }
}

Get a task (with time-log entries)

Each log entry carries the task-LOG guid needed by the log edit/delete endpoints.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Start a task timer

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Stop the timer / log time

Stops the running timer. Send adv: 1 with date/h/p to record a specific dated time entry instead.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Request Body schema: application/json
optional
description
string
adv
string

1 to record a manual dated entry.

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).

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "adv": "string",
  • "date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "h": "string",
  • "p": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Archive a task

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Edit a task-log entry

Takes the task-LOG entry's guid (from a task's log list), not the task's guid.

Authorizations:
kontoOAuth
Request Body schema: application/json
required
guid
required
string

Task-LOG entry guid.

description
string
date
string <date>
end_date
string <date>
h
string
p
string

Responses

Request samples

Content type
application/json
{
  • "guid": "string",
  • "description": "string",
  • "date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "h": "string",
  • "p": "string"
}

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Delete a task-log entry

Irreversible. Takes the task-LOG entry's guid, not the task's guid.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

Task-LOG entry guid.

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Product sales

Read-only sell pages. Scope: sell_product.

List product sales (sell pages)

Read-only. Each result has a sale type: STAND, SUB, DONA, EVENT. Only EVENT sales have attendees.

Authorizations:
kontoOAuth
query Parameters
search_text
string
limit
integer
Default: 10

Results per page (default 10).

page
integer
Default: 1

Page number (default 1).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}

Count product sales

Authorizations:
kontoOAuth
query Parameters
search_text
string

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": {
    }
}

List attendees of an EVENT sale

The guid must belong to an EVENT-type sale.

Authorizations:
kontoOAuth
path Parameters
guid
required
string

The resource's GUID.

query Parameters
limit
integer
Default: 10

Results per page (default 10).

page
integer
Default: 1

Page number (default 1).

Responses

Response samples

Content type
application/json
{
  • "status": true,
  • "message": "string",
  • "result": null
}