API/Consume a mandate
v1.0.0-beta.mdGet API keys
Mandates

Consume a mandate

POST /functions/v1/mandate-consume

The only call that moves the ceiling. Arithmetic happens under SELECT … FOR UPDATE, and Idempotency-Key is mandatory so a network timeout is never a double charge.

Server key. Idempotency-Key is mandatory, 8–200 characters, plus x-sidaxis-timestamp and x-sidaxis-nonce.

Body

FieldTypeNotes
mandate_iduuid, required
scopestring, requiredMatched exactly
amountintegerMinor unit
currencystringISO-4217
action_refstringYour reference for the action being authorised
contextobjectmerchant, category, country
curl -X POST https://api.sidaxis.com/functions/v1/mandate-consume \
  -H "x-sidaxis-api-key: sk_live_..." \
  -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" }
  }'

Response — always 200

Allowed
{
  "allowed": true,
  "consumption_id": "cns_5b7e21",
  "idempotent_replay": false,
  "remaining": 31100,
  "at_limit": false,
  "period_resets_at": "2026-09-17T03:00:00Z"
}
Refused
{
  "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
}

Concurrency

All arithmetic happens inside mandate_consume_atomic(), which takes SELECT … FOR UPDATE on the mandate row before summing consumptions. Reading the balance unlocked and writing afterwards lets two agents through and blows the ceiling — that is the bug this design prevents.

Idempotency

Without the header the call is refused with reason: idempotency_key_required, because a network timeout would otherwise become a double charge. The same key replayed returns the original consumption with idempotent_replay: true and debits once. See idempotency.

Append-only

Consumptions are rows, not a decremented column. A counter loses the reason, and the reason is what an audit needs.

Two more facts

  • at_limit: true means this consumption used the last of the period; a mandate.at_limit webhook follows — see webhooks.
  • When a step-up mandate exists, consuming it does not touch the parent: the standing mandate keeps its balance for the operations that still fit inside it.
Sidaxis is the human authorisation layer. It never moves money, holds funds or settles. The machine-readable contract is openapi.yaml.
Sidaxis API documentationQuickstartAuthenticationHosted or headlessSandbox and productionIdempotencyRate limitsErrors and refusalsField namesWebhooksAssuranceThe document ruleAlias availabilityMerchant themeMCP serverCompatibilityStatusRoadmapChangelogIdentityEnroll an identityRecognise a personDisclose an attributeMandatesThe eight scopesIssue a mandateCheck an actionConsume a mandateRead a mandateRevoke a mandateReceiptsRead a merchant's receiptsVerify a receiptHosted sessionsCreate a hosted sessionConsume a hosted sessionOne Face for agents