Skip to content

Authentication & scopes

The Agent API uses OAuth 2.1 (authorization-code + PKCE). A Konto user signs in, consents to a set of scopes, and your app receives tokens that act on their account. Tokens are bearer tokens sent as Authorization: Bearer <token>.

The OAuth endpoints live under /strax/agent; the resource endpoints under /api/v1/agent.

The flow

1. Redirect the user to   GET  /strax/agent/authorize   → they sign in & consent
2. Konto redirects back to your redirect_uri with ?code=…&state=…
3. Exchange the code:      POST /strax/agent/token       → access + refresh tokens
4. Call the API:          Authorization: Bearer <access_token>
5. On expiry, refresh:    POST /strax/agent/token (grant_type=refresh_token)

1 · Authorize

GET /strax/agent/authorize with client_id, scope (comma-separated), redirect_uri (must exactly match the one registered for your client), state, and — for public clients — a PKCE code_challenge (S256 only). The authorization code returned is valid for 10 minutes.

2 · Token

POST /strax/agent/token (JSON body) with grant_type=authorization_code, client_id, client_secret (confidential clients), code, and redirect_uri. Returns:

{ "access_token": "…", "refresh_token": "…", "expires_in": 3600, "scope": "…" }

3 · Refresh — the refresh token rotates

POST /strax/agent/token with grant_type=refresh_token + refresh_token (no redirect_uri needed). Each refresh returns a new refresh_token — you must persist it, or the next refresh fails. Refresh a little before expiry.

401 ≠ token expired

Agent endpoints return 401 for non-token reasons too (e.g. a missing account record). Don't blindly refresh-and-retry on every 401 — only treat it as expiry when the error says so (token_expired / mentions token/expired). Otherwise you'll loop.

Scopes

The user grants scopes at consent; your token can only do what was granted, and Konto only offers scopes the account's plan includes.

Scope Unlocks
dashboard_data Account status / identity (/agent/status)
manage_customers Customers — list, view, create, update
nav Items + reading & updating invoices
create_invoice Issuing invoices & quotes
recurring Recurring-invoice schedules
cost Costs/expenses — list, view, create (incl. OCR), update, delete
task Tasks & time tracking
sell_product Reading product sales & attendees

Request the least you need. A call outside your granted scopes returns 403.

Clients are per-environment

A client registered on dev.konto.is does not exist on konto.is (and vice versa). Using the wrong-environment client_id returns "Invalid client or redirect URI". Register (or ask Konto to register) one client per environment, each with its exact redirect_uri.

For shared apps (many merchants authorize the same client — e.g. a marketplace plugin), Konto flags the client as an app client so any user can consent; the grant binds to the consenting user.

Legacy alternative (server-to-server)

Unattended services with no user to sign in can use the legacy REST API with a username + api_key (HTTP Basic or form fields) instead of OAuth. See the in-app reference.