Skip to main content
Kordio Control has two callers, and they authenticate differently because they are trusted differently. An agent able to widen its own limits is not governed by them, so the separation is the point rather than a formality. An agent key can never write policy, and a dashboard token can never authorize an action as an agent.
Integrating the ledger instead? It uses OAuth 2.0 client credentials, documented on Ledger: OAuth client credentials. Nothing on this page applies there.

Getting your credentials

Everything below needs a workspace and a dashboard token, so start here.
  1. Sign up at app.kordio.io and create a workspace. You become its owner, which carries every capability.
  2. Your workspace slug is the one in the console URL: app.kordio.io/{slug}. It is the {workspace_slug} path segment in every management call.
  3. Your dashboard token is the identity token the console holds after sign-in. For scripting, mint one directly:
200 OK
access_token is the dashboard token. It is short-lived; exchange the refresh_token at POST /v1/auth/refresh rather than re-sending credentials. If your account has MFA enabled, sign-in answers 401 with code mfa_required and a pending_authentication_token to complete at POST /v1/auth/verify_mfa.
A dashboard token carries your full capability set in the workspace. It is not an agent credential and must never be given to an agent. Agents get an agent key, which cannot write policy.
Set both for the rest of the docs:

Agent keys

This is the credential your agent carries. Create an agent and the key is returned exactly once:
201 Created
Kordio stores only a digest and compares it in constant time. api_key cannot be shown again; if you lose it, rotate the agent. Keys are prefixed by mode, krt_test_... or krt_live_..., so a test key can never reach live data. The agent arrives with an active starter_policy: 500onasingleaction,andanythingover500 on a single action, and anything over 100 held for a person. It governs from the first request, and it keeps governing until you disable it, so a threshold you write later does not replace it. Send "skip_starter_policy": true to create an agent with nothing attached, which denies everything with no_policy until you write a rule. Send it as a bearer token:

Scopes

scopes restricts which action types a key may even ask about: an exact match (payment.create), a namespace wildcard (payment.*), or *. An empty array means unrestricted. A request outside the key’s scopes is refused by an intrinsic rule before any policy runs, and the decision names runtime_scope as what refused it. Scope narrowly, and use one agent per workload. A key shared across two workloads buys you nothing and costs you the ability to revoke one of them without stopping the other.

Rotating and revoking

An agent is active, suspended, or revoked, changed with PATCH /control/v1/workspaces/{slug}/agents/{id}. Suspending stops new authorizations and leaves history intact; revoking is permanent. Neither rewrites decisions already made, and neither invalidates a cosignature already issued, which stays verifiable until it expires. Cosignature lifetime is minutes, so that window is small, but it is not zero. See what Kordio guarantees.

Dashboard tokens and capabilities

Everything under /control/v1/workspaces/{slug}/* uses the identity token: creating agents, writing policy, reading intents, resolving approvals, managing billing.
Capabilities come from your role in that workspace, and the API enforces them: approve and manage_policy are deliberately separate. The person who authorises a payment need not be the person who can widen the rule that held it, which is most of what an auditor is looking for. Every role can read the audit trail, including member. An audit trail only some people can see is not much of one.

Test and live

Every credential is bound to one mode and the two never mix. A test agent key cannot touch live data, and a live agent cannot be created on a plan without live mode. Test mode runs the same policy engine, returns the same shapes, and issues real cosignatures. That is deliberate: you can prove an entire integration, including signature verification inside your own executor, before any money is at stake. Control-plane responses carry no livemode field. The mode is a property of the agent, so read it from GET /control/v1/workspaces/{slug}/agents/{id}, or from agent_mode inside a decision. The ledger API does echo livemode on every response, so do not write one client that assumes both.

When something is refused

A 404 where you expected a 403 is usually a workspace or agent mismatch, not a missing record.

Next steps

Authorize an agent action

Put the check in front of a real spend.

Errors

Every code and every rule that can refuse.