Prerequisites
Resolve offer and slot before declaring intent.
providerHsoIdThe provider x HSO x SCP offer identifier returned by offer/provider discovery.availabilitySlotIdAn open slot returned by provider availability.Health KeyRequired before declare-intent. IA2 is required before authorization and later transactable steps.AuthorizationPatient user sessions can act directly. Patient agents need BOOK for transitions and read permissions for lookups.Sandbox keys already satisfy these preconditions. An
odk_sandbox_ key acts as a synthetic patient provisioned at signup with an active IA2 Health Key and Layer-2 BOOK/CANCEL consent, and the server auto-mints an open sandbox slot at declare-intent (so availabilitySlotId may be omitted). You do not build the Health-Key/IA2/consent ceremony to run this flow in sandbox — see the quickstart.State machine
The first booking path is S0 through S4.
1
Declare intent.Creates the pending booking context and records S0_draft -> S1_intent in the ledger.
2
Authorize.Requires a transactable IA2 Health Key and locks the HSO instance price.
3
Accept terms.Binds the patient to the transaction terms and prepares the payment boundary.
4
Commit.Atomically commits escrow and slot reservation. This is the irreversible booking step.
Sandbox and live are the same machine. Sandbox keys run every transition of this state machine today against a synthetic provider with simulated payments. Live-mode commits — real providers, real money — open with our first design partners on per-partner
odk_live_ keys.Example
Raw HTTP sequence.
curl https://api.opendoc.com/transactions/declare-intent \
-X POST \
-H "Authorization: Bearer $OPENDOC_IDENTITY_OR_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"providerHsoId": "00000000-0000-4000-8000-000000000001",
"availabilitySlotId": "00000000-0000-4000-8000-000000000002",
"idempotencyKey": "txn-demo-001-declare"
}'
curl https://api.opendoc.com/transactions/$TRANSACTION_ID/authorize \
-X POST \
-H "Authorization: Bearer $OPENDOC_IDENTITY_OR_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "idempotencyKey": "txn-demo-001-authorize" }'
curl https://api.opendoc.com/transactions/$TRANSACTION_ID/accept-terms \
-X POST \
-H "Authorization: Bearer $OPENDOC_IDENTITY_OR_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "idempotencyKey": "txn-demo-001-terms" }'
curl https://api.opendoc.com/transactions/$TRANSACTION_ID/commit \
-X POST \
-H "Authorization: Bearer $OPENDOC_IDENTITY_OR_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "idempotencyKey": "txn-demo-001-commit" }'
Readback
Read the current transaction state.
Use transaction readback after each transition if your UI or agent needs to render a checkpoint, recover from a network retry, or audit the current booking state.
curl https://api.opendoc.com/transactions/$TRANSACTION_ID \ -H "Authorization: Bearer $OPENDOC_IDENTITY_OR_AGENT_TOKEN"
Idempotency matters. Send a stable idempotency key for every state-mutating call. Retries with the same key should return the original transition result instead of creating duplicate work.