Quickstart
From a sandbox key to an agent acting inside a mandate: enroll a live human, authorise an act, issue a mandate with a ceiling, then consume it idempotently.
Every call below is real and answers today. Copy them in order and the last one debits a ceiling.
1. Get a sandbox key
Sandbox is the merchant plus the key prefix: sk_test_, pk_test_. There is no separate host and no environment switch — isolation is by merchant_id. See sandbox.
2. Prove a human
From the browser, with a pk_ key. The account is born with face and voice; no document is asked for here. user_id is minted by the engine (the auth.users UUID) — a surface never supplies, chooses or guesses one.
curl -X POST https://api.sidaxis.com/functions/v1/process-biovital-enrollment \
-H "x-sidaxis-api-key: pk_test_..." \
-H "content-type: application/json" \
-d '{
"action": "ACTION_GENESIS",
"merchant_id": "mrc_9f2c",
"sieve_hash": "b41d...",
"consent": { "version": "2026-06", "locale": "en", "accepted_at": "2026-09-16T12:00:03Z" },
"device_signature": "ed25519:...",
"client_instance_id": "ci_3f8a",
"device_label": "iPhone 15",
"face_template": { "vector": [0.0121, -0.4412, "... 128 numbers total"], "quality": 0.93 },
"biometric_vitals": {
"bpm": 74, "hrv": 41, "stress_score": 0.18,
"voice_pulse_correlation": 0.86,
"liveness_confidence": 0.97, "liveness_proof": "rppg:..."
}
}'3. Authorise an act
From your server, with an sk_ key. amount is an integer in the minor unit — 4000 is forty dollars. The row this call writes is the capture a mandate accepts as proof, and it is valid for five minutes.
curl -X POST https://api.sidaxis.com/functions/v1/process-biovital-transaction \
-H "x-sidaxis-api-key: sk_test_..." \
-H "x-sidaxis-timestamp: 1789564803" \
-H "x-sidaxis-nonce: 9f2c41ab7d" \
-H "content-type: application/json" \
-d '{
"action": "ACTION_PAYMENT",
"merchant_id": "mrc_9f2c",
"sieve_hash": "b41d...",
"user_id": "0f9c2a51-7c33-4a1e-9b02-16c2b7f0d5aa",
"amount": 4000,
"currency": "USD",
"face_template": { "vector": ["... 128 numbers"], "quality": 0.94 },
"biometric_vitals": { "bpm": 71, "voice_pulse_correlation": 0.88, "liveness_confidence": 0.96 }
}'{
"success": true,
"capture_id": "cap_7f31c9a2",
"assurance_level": "face_voice",
"receipt_code": "RCP-4K2M-9QX7",
"sieve_hash": "b41d..."
}4. Issue a mandate
proof.capture_id comes from step 3 and must be no older than five minutes. assurance_level is read from the level frozen on that capture and is never sent by the client.
curl -X POST https://api.sidaxis.com/functions/v1/mandate-issue \
-H "x-sidaxis-api-key: sk_test_..." \
-H "x-sidaxis-timestamp: 1789564821" \
-H "x-sidaxis-nonce: 41c8de92aa" \
-H "content-type: application/json" \
-d '{
"granted_by": "0f9c2a51-7c33-4a1e-9b02-16c2b7f0d5aa",
"granted_to": "agt_3f77c1de",
"granted_to_kind": "agent",
"agent_display_name": "Your travel assistant",
"agent_descriptor": "Books flights and hotels inside the limit you set",
"scopes": ["payment"],
"constraints": { "merchant_allowlist": ["mrc_9f2c"], "country_allowlist": ["US"] },
"ceiling": { "kind": "amount", "amount": 50000, "currency": "USD", "period": "daily" },
"expires_at": "2026-12-31T23:59:59Z",
"proof": { "capture_id": "cap_7f31c9a2" }
}'5. Let the agent act
mandate-consume is the only call that moves the ceiling, and Idempotency-Key is mandatory: without it a network timeout becomes a double charge.
curl -X POST https://api.sidaxis.com/functions/v1/mandate-consume \
-H "x-sidaxis-api-key: sk_test_..." \
-H "Idempotency-Key: booking-88213-attempt-1" \
-H "x-sidaxis-timestamp: 1789564902" \
-H "x-sidaxis-nonce: 7de1a9c034" \
-H "content-type: application/json" \
-d '{
"mandate_id": "mdt_a91f3c",
"scope": "payment",
"amount": 18900,
"currency": "USD",
"action_ref": "booking-88213",
"context": { "merchant": "mrc_9f2c", "category": "travel", "country": "US" }
}'{
"allowed": false,
"reason": "ceiling_exceeded",
"developer_message": "Requested 18900 exceeds the remaining daily ceiling of 12000.",
"user_message": "This is above the daily limit you set.",
"step_up_available": true,
"remaining": 12000,
"period_resets_at": "2026-09-17T03:00:00Z"
}Branch on reason. A refusal is the layer working, not an error to catch. mandate-check is not part of this path: it is the advisory “could I plan this?” call and it authorises nothing — see mandates/check.
6. Read the receipt
curl -X POST https://api.sidaxis.com/rest/v1/rpc/get_receipt_v2 \
-H "apikey: <publishable anon key>" \
-H "content-type: application/json" \
-d '{ "lookup_key": "RCP-4K2M-9QX7" }'The response carries the assurance block — face, face_voice or face_voice_doc — and, when a mandate authorised the act, the agent's name. See receipts/verify and assurance.
The replay headers
x-sidaxis-timestamp (unix seconds, accepted within ±300 s) and x-sidaxis-nonce (at least 8 characters, single use) are required on face-identify, process-biovital-transaction and every mandate-* call. They make a captured request useless to replay.