Skip to main content

Create the authorization

The commitment is sha256: followed by the hex SHA-256 of the domain line attesso:authorization:commitment:v1 plus a newline, concatenated with 32 random bytes (the opening). Keep the opening server-side and reveal it only at commit. A commitment cannot be reused within an Organization. The response is the durable record. Gate on its three values, not on the HTTP status:
A refusal is also 201, with decision: "DENY", state: "DENIED", and can_execute: false. reason.violations[] names the path and the policy code. The codes are listed on Errors and idempotency. A Mandate has one reservation in flight. A second authorization while one is RESERVED is denied with MANDATE_UNAVAILABLE and creates no reservation.

Gate execution

Execute only when the latest Authorization has all three values:
Start and finish before execute_before, and ensure any external credential cannot act after that deadline.

Commit after acceptance

Commit means the external executor accepted the action. It does not mean a card was created, a payment settled, or a service was fulfilled.
The opening must open the commitment recorded when the authorization was created; otherwise the commit is refused and nothing is recorded. A successful commit atomically changes the Authorization to COMMITTED. A SINGLE_USE Mandate becomes CONSUMED; a RECURRING Mandate stays ACTIVE. The response is the Authorization in its committed state:
For the full pattern of taking an ALLOW and executing it on your own payment provider, see bind an authorization to your PSP.

Cancel only when execution is impossible

Disable every external card, token, job, or provider capability before calling the cancellation endpoint. Cancelling does not refund a recurring period’s consumed budget: current_period.consumed_amount keeps counting the cancelled reservation.
Use NEVER_BECAME_POSSIBLE only when no external capability was ever usable. Cancellation is outcome-idempotent: cancelling an Authorization that is already CANCELLED succeeds and returns the same state; nothing is released twice.

Resolve an uncertain response

1

Stop new execution

A timeout or 503 never grants permission. Do not start another action.
2

Read current state

Retrieve GET /v1/authorizations/{authorization_id}.
3

Replay the same operation

If still appropriate, retry with the same idempotency key and identical body.
4

Escalate terminal conflicts

A committed, cancelled, or expired Authorization cannot transition again. A commit against an Authorization that is no longer RESERVED fails with 409 (RESOURCE_STATE_CONFLICT, retryable: false): re-read the state and reconcile instead of retrying.
When the outcome is ambiguous, follow the reconciliation decision table before committing or canceling: a timeout is not proof the provider did nothing.