Kordio Control events are a separate subscription, registered per workspace with a different
event set and a different retry schedule. See Kordio Control: webhooks. The
signing algorithm is the same, so the routine below verifies either, but read the header name
off the request rather than hard-coding one.
Register an endpoint
Ledger endpoints are per tenant and needledger:write.
201 Created
signing_secret here and secret on the spend control side. The two APIs differ;
do not share a parser.
Event types
Ingestion itself emits no per-row events; a 10k-row batch would flood the stream. Use
reconciliation.run_completed plus GET /v1/external_transactions?status=open for the break
workflow. Additional oauth_client.*, member.*, tenant.* and reserve.* events exist for
account-management surfaces. Subscribe only to what you handle.
A plain period close emits nothing. Only period.closed_forced fires, so a subscriber cannot use
these events to learn that a period closed cleanly; read GET /v1/period_closes for that.
transaction.reversal_created is emitted before transaction.reversed on purpose. A subscriber
rebuilding state from the tail can apply the new transaction before applying the link from the
original to its reversal.
Verify the signature
Each delivery includes aKordio-Signature header: an HMAC-SHA256 over
<timestamp>.<raw_body>, keyed by the endpoint’s signing secret.
Respond and retry
A delivery succeeds on any2xx. Any non-2xx, timeout, or network error is retried with
exponential backoff:
After the fifth failed attempt the delivery is marked dead. Return
2xx quickly and do heavy
work asynchronously. Events carry stable ids, so treat handlers as at-least-once and deduplicate
on the event id.
You can inspect deliveries for an endpoint, count failures, redeliver a specific delivery, or
send a test event from the webhook endpoints
API.
Events tail and replay
Every state-changing operation also lands in the durable events log, with the same payloads webhooks deliver. If an endpoint was down or you need to backfill, pull from the tail instead of relying on retries.type and time. since
takes an ISO 8601 timestamp or a relative form like 24h, 7d or 30m. Fetch a single event
with GET /v1/events/{id}.
This is the safe way to rebuild state after an outage, and it is not the audit trail. An event is
written just after its transaction commits, so a crash in that window loses the event and keeps
the transaction. The postings are what an audit reads.
Next steps
Reconciliation
The workflow
reconciliation.run_completed drives.Pagination
Walking the events tail with cursors.