Errors
AgentCard returns errors as JSON with an HTTP status code:
json
{
"error": "Withdrawal exceeds remaining card balance",
"code": "insufficient_card_balance"
}| Field | Description |
|---|---|
error | Human-readable message. May change; do not parse it. |
code | Stable machine-readable code. Branch on this. |
details | Optional extra data, e.g. details.field for validation errors or details.pendingRequestId for a request already in progress. |
General rules
- 4xx: fix the request or follow the action below. Retrying unchanged will fail again.
- 429: a limit was reached. Wait and retry later.
- 5xx: temporary. Retry later with backoff. If you had already submitted a payment, do not pay again: poll
GET /cards/requests/{pendingRequestId}instead. - Never start a new issuance or recharge to "retry" a payment. Continue the original
pendingRequestId.
Authentication
| Status | code | What to do |
|---|---|---|
| 401 | authorization_required | Send Authorization: Bearer <agent-vc>. |
| 401 | vc_expired | Get a new challenge and VC. |
| 403 | vc_challenge_expired, vc_challenge_invalid, vc_challenge_missing, vc_challenge_agent_mismatch | Get a new challenge from POST /auth/challenge and mint a new VC for it. |
| 403 | vc_audience_mismatch | Mint the VC with the audience returned by POST /auth/challenge. |
| 403 | vc_invalid, vc_wrong_type, vc_issuer_mismatch, vc_sub_missing | Send an Agent VC, not a login JWT. |
| 403 | agent_not_linked | Link the agent to a FluxA Wallet (fluxa-wallet link-wallet), then retry. |
See Authentication.
Card type and eligibility
| Status | code | What to do |
|---|---|---|
| 400 | card_type_selector_required | Send exactly one of cardTypeId, binId, bin. |
| 400 | card_type_selector_invalid | The selector is malformed (bin must be 6–10 digits). |
| 400 | card_type_amount_out_of_range | Use an amount within the product's limits. |
| 404 | card_type_not_found | Use an ID from GET /card-types. |
| 409 | card_type_ambiguous | The bin matches several products. Use cardTypeId. |
| 409 | card_type_unavailable | The product is not open for applications. Choose another. |
| 403 | vip_whitelist_required | The user must apply for this product in FluxA Wallet (details.applicationUrl when present), then retry. Do not pay. |
| 503 | card_access_unavailable | Eligibility could not be checked. Retry later. This is not a rejection. |
| 503 | card_types_unavailable, card_issuance_paused | New cards are temporarily unavailable. Retry later. |
Cardholder
| Status | code | What to do |
|---|---|---|
| 404 | cardholder_not_found | Create a cardholder profile. |
| 409 | cardholder_required, cardholder_not_approved | Create the profile or wait until kycStatus is approved. |
| 409 | bank_holder_action_required | The cardholder details need attention. Check the profile and ask the user to correct them. |
| 409 | kyc_in_progress | Verification is in progress. Wait. |
| 409 | name_locked | The verified name cannot be changed. |
| 409 | revision_conflict | Re-read the profile and retry with the current revision. |
| 400 | revision_invalid | If-Match must be a positive integer. |
| 422 | profile_invalid | Fix the field named in details.field. |
| 429 | rate_limited | Wait a minute and retry. |
Amounts and limits
| Status | code | What to do |
|---|---|---|
| 400 | invalid_amount | Use a valid USD amount in the range stated in the message. For withdrawals, the amount must be larger than the fee. |
| 400 | card_balance_limit_exceeded | The card balance would exceed its cap. Use a smaller amount. |
| 400 | insufficient_card_balance | The withdrawal is more than the card balance. |
| 409 | card_limit_reached | The account has the maximum number of cards. |
| 429 | daily_card_limit_reached | New cards are limited for today. Try tomorrow. |
| 429 | daily_withdraw_limit_reached | Withdrawals are limited for today. Try tomorrow. |
| 503 | card_limits_unavailable | Limits could not be checked. Retry before paying. |
Cards, requests and payments
| Status | code | What to do |
|---|---|---|
| 400 | invalid_card_id | Use a card_… ID. |
| 404 | card_not_found | The card does not exist in this account. |
| 409 | card_not_active | The card is not active. Check its status. |
| 400 | recharge_not_supported, withdraw_not_supported | This card does not support the operation. |
| 409 | recharge_in_progress | Continue the recharge in details.pendingRequestId. |
| 409 | withdrawal_in_progress | Wait for the current withdrawal to finish. |
| 404 | withdrawal_not_found | Check the withdrawal ID. |
| 400 | missing_pending_request_id, missing_payment_payload | Send both pendingRequestId and paymentPayloadB64. |
| 400 | pending_request_type_mismatch | Use /cards/complete for issuance and /recharge/complete for recharges. |
| 400 | pending_request_card_mismatch | The recharge request belongs to a different card. |
| 403 | pending_request_forbidden | The request belongs to another account. |
| 404 | pending_request_not_found | Check the pendingRequestId. |
| 409 | pending_request_invalid_status | The request is no longer payable. Get the request to see where it is. |
| 410 | pending_request_expired | The payment window passed. Start a new request. |
| 400 | invalid_transaction_type | Use a supported type filter. |
Service errors
| Status | code | What to do |
|---|---|---|
| 502 / 503 / 504 | card_provider_error, card_service_error, other codes | Temporary. Retry later. If a payment was already submitted, poll the request instead of paying again. If it persists, contact FluxA support. |
