View Markdown

Responses

How a human (or a delegate) settles an ask.

Generated from the contract, version 2.0.0-draft.2 (OpenAPI). Base URL https://usekabu.com/api. Errors are problem details, each code with its own page.

A human responds to an ask

POST/v2/messages/{message_id}/responses

Called by the Kabu apps, by the answer page behind a delivered link, or by an integrator key with answers:delegate (recorded as delegated, with asserted_by). Any key holding messages:write gets 403 self_response_forbidden (test mode excepted), so an agent can never answer its own or a sibling’s ask. After settlement: 409 already_settled with the settled message; after the deadline: 410 ask_expired.

  • Auth: an API key, or a signed-in human’s token (the Kabu apps).
  • Scopes: answers:delegate.
  • Refused to: a key holding messages:write.
  • Signed-in humans: audience.
Parameter In Type Required Description
message_id path string Required A msg_… id.
Idempotency-Key header string, at most 255 characters Optional Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h.
Kabu-Org header string Optional Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner.

Request body: ResponseInput.

Status Means Body
200 Settled; the message with its resolution. Message
4XX Error Problem
5XX Error Problem
curl -X POST "https://usekabu.com/api/v2/messages/$MESSAGE_ID/responses" \
  -H "Authorization: Bearer $KABU_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"decision":"approve"}'

Mint a single-use answer link for one recipient

POST/v2/messages/{message_id}/answer_links

For integrators who deliver asks through their own channels. Audited. A key holding messages:write gets 403 self_response_forbidden. Kabu-delivered links never appear in API bodies.

  • Auth: an API key.
  • Scopes: answers:delegate.
  • Refused to: a key holding messages:write.
Parameter In Type Required Description
message_id path string Required A msg_… id.
Idempotency-Key header string, at most 255 characters Optional Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h.

Request body: AnswerLinkCreate.

Status Means Body
201 OK AnswerLink
4XX Error Problem
5XX Error Problem
curl -X POST "https://usekabu.com/api/v2/messages/$MESSAGE_ID/answer_links" \
  -H "Authorization: Bearer $KABU_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"recipient":"…"}'

Verify a receipt and return its claims

POST/v2/receipts/verify

For integrators without a JWS library. Checks signature, issuer and that the receipt belongs to the caller’s org and mode; an invalid receipt is 422 invalid_receipt. Offline verification against /.well-known/jwks.json gives the same answer.

  • Auth: an API key, or a signed-in human’s token (the Kabu apps).
  • Scopes: messages:read.
  • Signed-in humans: audience.
Parameter In Type Required Description
Kabu-Org header string Optional Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner.

Request body: ReceiptVerify.

Status Means Body
200 OK ReceiptClaims
4XX Error Problem
5XX Error Problem
curl -X POST "https://usekabu.com/api/v2/receipts/verify" \
  -H "Authorization: Bearer $KABU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"receipt":"…"}'

Schemas

ResponseInput

Validated against the stored ask. as_recipient is required for delegated responses and ignored otherwise.

Type: ApproveInput or RejectInput or IgnoreInput or EditInput or RespondInput.

Chosen by decision: "approve": ApproveInput, "reject": RejectInput, "ignore": IgnoreInput, "edit": EditInput, "respond": RespondInput.

ApproveInput

option is required when the ask offers more than one approve option (e.g. once vs session).

Property Type Required Description
decision "approve" Required
option string Optional
comment string, at most 1000 characters Optional
as_recipient RecipientRef Optional rcp_…, ext:<your external id>, or me (the key’s default_to).
surface Surface Optional Records via for a user token only; never raises assurance. Links remain link, delegates delegated. Web BFF forces web.

Unknown properties are refused.

Surface

Records via for a user token only; never raises assurance. Links remain link, delegates delegated. Web BFF forces web.

Type: string, one of "app", "lock_screen", "watch", "live_activity", "web".

RejectInput

Property Type Required Description
decision "reject" Required
option string Optional
comment string, at most 1000 characters Optional
as_recipient RecipientRef Optional rcp_…, ext:<your external id>, or me (the key’s default_to).
surface Surface Optional Records via for a user token only; never raises assurance. Links remain link, delegates delegated. Web BFF forces web.

Unknown properties are refused.

IgnoreInput

Property Type Required Description
decision "ignore" Required
option string Required
comment string, at most 1000 characters Optional
as_recipient RecipientRef Optional rcp_…, ext:<your external id>, or me (the key’s default_to).
surface Surface Optional Records via for a user token only; never raises assurance. Links remain link, delegates delegated. Web BFF forces web.

Unknown properties are refused.

EditInput

Only when the ask has action and allow_edit. A full replacement of action.args, validated against args_schema.

Property Type Required Description
decision "edit" Required
edited_args object, at least 1 keys Required
comment string, at most 1000 characters Optional
as_recipient RecipientRef Optional rcp_…, ext:<your external id>, or me (the key’s default_to).
surface Surface Optional Records via for a user token only; never raises assurance. Links remain link, delegates delegated. Web BFF forces web.

Unknown properties are refused.

RespondInput

Exactly one of: option (single choice), options (multiple choice), text (text ask, or choice with allow_other), values (form). Anything else is 400.

Property Type Required Description
decision "respond" Required
option string Optional
options array of string, 1 to 12 items Optional
text string, at most 4000 characters Optional
values FormValues Optional
confidence integer, from 1 to 5 Optional
comment string, at most 1000 characters Optional
as_recipient RecipientRef Optional rcp_…, ext:<your external id>, or me (the key’s default_to).
surface Surface Optional Records via for a user token only; never raises assurance. Links remain link, delegates delegated. Web BFF forces web.

Unknown properties are refused.

AnswerLinkCreate

Property Type Required Description
recipient RecipientRef Required rcp_…, ext:<your external id>, or me (the key’s default_to).
expires_in integer, from 60 to 86400 Optional

Unknown properties are refused.

ReceiptVerify

Property Type Required Description
receipt string, at most 8192 characters Required

Unknown properties are refused.

ReceiptClaims

The signed payload of Resolution.receipt. Kabu attests what it recorded: the proposal it delivered and the response it received, not pixels seen or downstream execution. Keys rotate yearly and remain in the JWKS for the audit period; alg must be ES256.

Property Type Required Description
v "1" Required
iss string Required https://api.usekabu.com
aud string Required The org id. Verifiers must check it.
livemode boolean Required
jti string Required Unique receipt id.
iat integer Required
msg string Required The message id.
rev integer Required Request revision; always 1 (asks are immutable).
req_digest string Required sha256 of RFC 8785 JSON of {org, livemode, msg, rev, title, body, blocks, links, attachments:[{media, sha256}], action, ask} with quiz.correct and all delivery state, URLs and receipts excluded.
decision string Required
value_digest string or null Required
effective_action_digest string or null Required
grant Grant or null Required
sub string Required The responding human (rcp_…) or system.
asserted_by string or null Required
assurance string Required
source string Required
via string Required
resolved_at integer Required