Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usemandate.io/llms.txt

Use this file to discover all available pages before exploring further.

When a request fails, Mandate returns a JSON body describing what went wrong. You can rely on the HTTP status code for broad error classification and on the error or detail field for machine-readable error codes that are safe to branch on in your code.

Error response format

Most endpoints return errors in this shape:
{
  "error": "mandate_expired",
  "message": "Mandate status: revoked"
}
Some endpoints — particularly those that raise FastAPI validation errors — return the detail key instead:
{
  "detail": "not_found"
}
Your error-handling code should check both keys.

HTTP status codes

StatusMeaning
200Request succeeded.
201Resource created successfully.
400Bad request — invalid input or an operation not permitted in this context.
401Unauthorized — Authorization header missing or key invalid.
402Payment required — policy denied the transaction or proof was rejected.
403Forbidden — API key revoked, or agent/mandate unauthorized.
404Not found — resource does not exist or does not belong to your account.
409Conflict — resource already exists (e.g. duplicate account email).
500Internal server error — unexpected failure on Mandate’s side.

Error codes

Error codeHTTP statusDescription
agent_revoked402The agent is not active. Revoked agents cannot authorize payments.
agent_not_found404The agent_id does not exist or does not belong to your account.
mandate_expired402The mandate is revoked, exhausted, or its expires_at timestamp has passed.
merchant_not_allowed402The merchant domain or resource category is not in the mandate’s allowlist.
amount_exceeds_per_transaction_limit402The requested amount exceeds the mandate’s max_spend_per_transaction limit.
total_budget_exceeded402The payment would push spent_total past the mandate’s max_spend_total budget.
payment_required402No payment proof was included in the request.
invalid_proof_header402The X-Payment-Proof header is present but cannot be parsed.
payment_verification_failed402The proof signature is invalid or the nonce has already been consumed.
nonce_reused400The proof nonce has already been used. Proofs are single-use to prevent replay attacks.
proof_expired400The proof timestamp is older than 5 minutes. Generate a fresh proof and retry.
invalid_signature400The HMAC-SHA256 signature in the proof does not match the expected value.
production_payments_not_supported400You called a sandbox-only endpoint (e.g. POST /v1/payments/proof) with a production API key.
developer_exists409An account with that email address is already registered.
not_found404The requested resource does not exist.

Handling errors in code

Check the HTTP status code first, then inspect the error code for precise handling:
TypeScript
const res = await fetch("https://api.kya.dev/v1/policy/evaluate", {
  method: "POST",
  headers: {
    Authorization: "Bearer ky_sand_••••••••••••••••",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ ... }),
});

if (!res.ok) {
  const body = await res.json();
  const code = body.error ?? body.detail;

  switch (code) {
    case "mandate_expired":
      // prompt the user to renew or create a new mandate
      break;
    case "amount_exceeds_per_transaction_limit":
      // reduce the requested amount or request a higher limit
      break;
    case "nonce_reused":
      // generate a new proof and retry
      break;
    default:
      throw new Error(`Mandate API error: ${code}`);
  }
}