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