Skip to main content
By the end of this page an agent of yours asks Kordio before it spends, and Kordio answers allowed, requires_approval, or denied, naming the rule that decided.
Wrong page? This gates what an agent is allowed to spend, before it spends it. If you are here to post double-entry transactions and read balances, you want the Ledger quickstart instead.
Everything here runs in test mode, which uses the same policy engine as live, so the integration you write now is the one you ship.

0. Get your credentials

Sign up at app.kordio.io, create a workspace, and mint a dashboard token. The full walkthrough is on getting your credentials.

1. Create an agent

An agent is a scoped identity for one workload. It carries its own API key and its own permitted action types.
201 Created
api_key is returned exactly once and starts with krt_test_. Store it the way you store any other secret; Kordio keeps only a digest and cannot show it to you again. scopes restricts which action types this key may even ask about. An empty array means unrestricted, not blocked. Name the action types you expect, and keep one agent per workload so you can revoke one without stopping the rest. Read starter_policy before you go further. A new agent arrives governed rather than open: a single action is capped at 500,andanythingover500, and anything over 100 is held for a person. Nothing you write later replaces it, so step 2 retires it. Pass "skip_starter_policy": true to create an agent with no policy at all, which denies everything until you write one.

2. Write your own policy

The starter policy is a floor, not the policy you want. Write yours alongside it:
That policy says: never more than 500inoneaction,holdanythingover500 in one action, hold anything over 2,000 for a person, and never more than $2,000 in any rolling hour. The third rule is the one that catches a retry loop. The first two, on their own, would let nineteen individually reasonable $340 charges through. Both policies are active now, and both run. Where two rules answer the same question the tighter one decides, so the starter’s 100thresholdwouldstillgovern,notyour100 threshold would still govern, not your 2,000 one. Retire it now that your rules cover its ground:
200 OK
Do that in this order, and never disable an agent’s last active policy. An agent with no active policy denies everything, with the rule no_policy. That is deliberate and fail-closed: an agent nobody has written rules for has no authority rather than unlimited authority.

3. Open a budget

A budget is the envelope for one run. Every authorized action commits against it, which makes it the thing that stops a loop rather than a single mistake.
201 Created

4. Ask before you spend

This is the call that matters. Put it in front of the action, not after it.
201 Created
policy_snapshot carries every active policy. Leave the starter enabled and it appears here too, with headroom reduced to the tightest value per key, which is how a threshold you wrote can be quietly overruled by one you did not. Read the status code, not the body, to branch: Idempotency-Key is required, and its absence is a 422, not a 400. Reuse the same key when you retry and Kordio replays the original decision instead of reserving the budget twice. The key is matched on its own: a replay returns the first decision even if you changed the amount or the counterparty underneath it, so give a genuinely different action a genuinely different key. decision.headroom reports what every limit had left, and decision.policy_snapshot is the policy exactly as it read at that moment. Both are measured before the reservation, so session_remaining_cents above is still the full $500: subtract cost_cents yourself for the figure after this action. Surface headroom to your agent so it can pick a cheaper path instead of retrying into the same wall. Raise cost_cents past your $2,000 threshold and this call answers 202 instead, with no cosignature. That is the product working, not a failure. See holding spend for a person for what happens next.

5. Report what happened

Kordio holds the budget reservation until you say how the action ended.
If it failed, say so instead. The reservation is released and the budget goes back:
Skipping this step is the most common integration mistake, and nothing sweeps up after it. A budget has no expiry and no close endpoint, so an action that is never completed or failed holds its share of the budget for good. Open a budget per run and let it end with the run.
Payments report the same way, through POST /control/v1/agent/payment_intents/:id/complete and /fail. Kordio authorizes the spend and hands you a cosignature; your own rail moves the money. See the payments section.

6. Try it without spending anything

simulate runs the whole policy evaluation and records no intent and no reservation. Use it in tests, and in your own UI to show someone what a policy would do before they save it.
200 OK
It always returns 200, whatever the outcome, and the decision has no id because no intent was created. policy_snapshot is abbreviated here; the real one repeats every column of every active policy.

Next steps

Writing a policy

Every rule kind, the typed shorthands, and the condition language.

Verifying an authorization

Check the cosignature offline, in your executor.

Holding spend for a person

What 202 means and how the queue resolves.

API reference

Every field on every endpoint.