Misar IO Docs

Errors & fail-closed

HTTP status codes and the fail-closed contract that prevents a billing outage from granting free usage.

Fail-closed contract

The single most important rule of the Universal Wallet: a failure denies usage, it never grants it.

When the ledger is unreachable, a request times out, or a response is malformed, callers must treat the operation as denied:

OperationOn failure
Deduct creditsallowed: false — do not run the billable feature
Read balance0 — degrade the UI gracefully
List transactionsempty page (items: [], nextCursor: null)
Create top-up sessionurl: null — surface a friendly retry message

The @misar/wallet SDK implements exactly this contract, so a transient outage can never silently grant free AI usage or phantom credits.

Never invert the default

Do not "allow on error" for convenience. If you cannot confirm the user has credits, you must not run the billable feature. This is the core security property of the wallet.

HTTP status codes

CodeMeaningTypical cause
200SuccessRequest processed. For deduct, still check allowed.
400Bad requestInvalid amountDollars (non-integer or outside 10–100000), missing required field, or invalid Stripe signature on the webhook.
401UnauthorizedMissing/invalid SSO bearer token.
403ForbiddenMissing/invalid x-wallet-service-key, or a bearer token attempting a service-key-only endpoint, or accessing another user's wallet without the service key.
429Rate limitedToo many requests. Back off and retry.
5xxServer errorLedger or upstream unavailable. Treat as fail-closed.

Validation errors

POST /io/wallet/topup-session rejects bad amounts before creating any Stripe session:

{ "error": "amount_dollars must be an integer" }
{ "error": "Minimum top-up is $10" }
{ "error": "Maximum top-up per transaction is $100,000" }

Retrying

  • 429 and 5xx are safe to retry with backoff.
  • When retrying a deduct, always send the same idempotency_key so the retry cannot double-charge. See Idempotency & concurrency.
  • A deduct that returns 200 with allowed: false is not an error to retry — the user is simply out of credits. Prompt a top-up instead.