Receipts
When an ask settles, its resolution.receipt is a compact JWS that Kabu signs (ES256): proof of what was asked, what
was decided, by whom, how, and when. Keep it with whatever the answer allowed, a deploy log or an audit trail, and
anyone can check later that the decision is Kabu’s record and was not edited.
What it says
The receipt’s payload is its claims:
| Claim | What it is |
|---|---|
msg |
The ask’s message id |
aud |
The org it belongs to: check it is yours |
req_digest |
A SHA-256 of what was shown: the title, body, blocks, links, attachments, action and ask, as canonical JSON (RFC 8785) |
decision |
approve, reject, edit, respond or ignore |
value_digest, effective_action_digest |
Digests of the answer’s value, and of the action as finally approved (with any edits) |
sub |
Who answered: the recipient (rcp_…), or system for an expiry default |
assurance, via, source |
How sure Kabu is it was them, where they answered, and whether a person or the system decided |
resolved_at, iat, jti |
When it settled, when it was signed, and the receipt’s own id |
Values are signed as digests, never as text, so a receipt stays verifiable after the message’s content is erased. A receipt proves what Kabu delivered and what it received back, not what a screen showed or what the agent did next.
Verify it
Offline, with any JWS library: fetch the public keys from
https://usekabu.com/.well-known/jwks.json, pick the key whose kid matches the receipt’s
header, check the signature with ES256 (no other algorithm), then check aud is your org and msg the ask you hold.
Keys rotate yearly and stay published for the audit period, so old receipts keep verifying.
Online, without a JWS library:
curl https://usekabu.com/api/v2/receipts/verify \
-H "Authorization: Bearer $KABU_API_KEY" \
-H "Content-Type: application/json" \
-d '{"receipt": "eyJhbGciOiJFUzI1NiIs…"}'It returns the claims when the receipt is valid and belongs to your org and mode, and 422
invalid_receipt when it does not.