Cards
Issue a card, follow the issuance request, then list cards, read balances and reveal card details.
All endpoints require Authorization: Bearer <agent-vc>. See Authentication.
Issue a card
Issuing a card is a two-step x402 payment:
- Initiate — choose a product and initial load. AgentCard returns a
pendingRequestIdand, once the request is payable, an x402paymentRequestfor the load plus the issuance fee. - Pay and complete — sign the
paymentRequestwith a mandate, then submit the signed payload.
If the product requires a cardholder that is still being reviewed, the request waits in pending_cardholder with no paymentRequest. Poll the request until it becomes payable.
CLI
One command runs the whole flow, including polling and signing:
fluxa-wallet card create --card-type-id <cardTypeId> --amount 25.00 --mandate <mandate_id>
# continue the same request later (do not start a new one):
fluxa-wallet card create --request-id <pendingRequestId> --mandate <mandate_id>--wait <seconds> (0–300, default 30) controls how long it polls.
Before you start
- Read card types and pick a product with
availability.canApply: true. - If the product has
requirements.cardholder: true, make sure the account has an approved cardholder. - Have a signed mandate in USDC whose remaining budget covers
amountUsd+ issuance fee. If you don't have one, create one and ask the user to sign it.
Initiate
/api/v2/cards/initiateBearer agent-vccurl -X POST https://agentcard.fluxapay.xyz/api/v2/cards/initiate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AGENT_VC" \
-d '{
"cardTypeId": "ct_63243cc4f38836aef2c62ca4",
"amountUsd": "25.00"
}'| Field | Type | Required | Description |
|---|---|---|---|
cardTypeId | binId | bin | string | exactly one | Product selector. See Selecting a product. |
amountUsd | string | yes | Initial load in USD, up to two decimals. Must be within the product's limits and your account limits; on 400 invalid_amount the error message states the allowed range. |
Response 200 (payable):
{
"pendingRequestId": "2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37",
"cardTypeId": "ct_63243cc4f38836aef2c62ca4",
"status": "pending_payment",
"amountUsd": "25.00",
"feeUsd": "1.00",
"totalUsd": "26.00",
"expiresAt": "2026-10-27T10:05:00.000Z",
"paymentRequest": {
"x402Version": 1,
"accepts": [
{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "26000000",
"asset": "0x833589fCD6Edb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x…",
"resource": "https://…",
"description": "…",
"maxTimeoutSeconds": 60,
"extra": { "name": "USD Coin", "version": "2" }
}
]
},
"paymentLinkId": "…",
"checkoutUrl": null
}Response 200 (waiting for cardholder review — no payment yet):
{
"pendingRequestId": "2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37",
"cardTypeId": "ct_63243cc4f38836aef2c62ca4",
"status": "pending_cardholder",
"amountUsd": "25.00",
"feeUsd": "1.00",
"totalUsd": "26.00",
"expiresAt": "2026-11-03T10:00:00.000Z"
}| Field | Description |
|---|---|
pendingRequestId | Keep this. Every retry, poll and completion uses the same ID. |
status | See Request statuses. |
amountUsd, feeUsd, totalUsd | Load, fee and the total you will pay (totalUsd = amountUsd + feeUsd). |
paymentRequest | x402 payment requirements. Present only when status is pending_payment. |
expiresAt | Pay before this time. A payable request is valid for a few minutes. |
Do not initiate again to retry
Each initiate call creates a new purchase request. To retry a payment or keep waiting, continue the same pendingRequestId with Get a request and Complete.
Sign the payment with a mandate
Sign paymentRequest with your mandate using the FluxA Wallet API. For an x402 version 1 request, map accepts[0] to the X402 V3 payment endpoint:
| X402 V3 field | Value |
|---|---|
mandateId | Your signed mandate |
scheme, network | accepts[0].scheme, accepts[0].network |
amount | accepts[0].maxAmountRequired |
currency | USDC |
assetAddress | accepts[0].asset |
payTo | accepts[0].payTo |
resource, host | accepts[0].resource and its host |
tokenName, tokenVersion | accepts[0].extra.name, accepts[0].extra.version |
The response's xPaymentB64 is the paymentPayloadB64 for the next step. The CLI does this mapping for you (including x402 version 2 requests).
Complete
/api/v2/cards/completeBearer agent-vccurl -X POST https://agentcard.fluxapay.xyz/api/v2/cards/complete \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AGENT_VC" \
-d '{
"pendingRequestId": "2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37",
"paymentPayloadB64": "<xPaymentB64>"
}'| Field | Type | Required |
|---|---|---|
pendingRequestId | string | yes |
paymentPayloadB64 | string | yes |
Response 201 — card issued:
{
"success": true,
"card": { "id": "card_7Hq2LmX9pRt4", "status": "active", "…": "see Card object" }
}Response 202 — payment received, card still being issued:
{
"success": false,
"status": "payment_submitted",
"pendingRequestId": "2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37",
"message": "Payment submitted; issuance will complete automatically once settlement is confirmed"
}On 202, do not sign or submit again. Poll Get a request until completed.
Get a request
/api/v2/cards/requests/{pendingRequestId}Bearer agent-vcReturns the current state of an issuance or recharge request.
curl https://agentcard.fluxapay.xyz/api/v2/cards/requests/2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37 \
-H "Authorization: Bearer $AGENT_VC"{
"pendingRequestId": "2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37",
"requestType": "issue",
"cardTypeId": "ct_63243cc4f38836aef2c62ca4",
"cardId": null,
"status": "completed",
"amountUsd": "25.00",
"feeUsd": "1.00",
"totalUsd": "26.00",
"expiresAt": "2026-10-27T10:05:00.000Z",
"card": { "id": "card_7Hq2LmX9pRt4", "status": "active", "…": "see Card object" }
}| Field | Description |
|---|---|
requestType | issue or recharge. |
cardId | For recharges, the card being recharged. null for issuance. |
paymentRequest | Present while status is pending_payment. |
card | The resulting card, once completed. |
nextAction | Present on some action_required responses. |
Request statuses
status | Meaning | What to do |
|---|---|---|
pending_cardholder | Waiting for cardholder review. No payment requested yet. | Poll this endpoint. |
pending_payment | Payable. paymentRequest is included. | Sign and complete before expiresAt. |
completed | Done. card is included. | Use the card. |
action_required | The cardholder details need attention. | Check GET /cardholders/get and ask the user to fix their details. |
expired | Not paid in time. No money was taken. | Start a new request. |
failed | The request could not be completed. | Start a new request if the user still wants a card. |
refunded | Payment was returned to the payer. | Start a new request if needed. |
| any other value | Processing (payment settling, card being issued, or funds being returned). | Keep polling the same ID. Do not pay again. |
Errors: 404 pending_request_not_found.
List cards
/api/v2/cardsBearer agent-vc# Cards issued by this agent
curl "https://agentcard.fluxapay.xyz/api/v2/cards?issuedBy=me" \
-H "Authorization: Bearer $AGENT_VC"| Query | Description |
|---|---|
issuedBy=me | Only cards issued by the calling agent. Omit to list every card in the linked account. |
{
"cards": [ { "id": "card_7Hq2LmX9pRt4", "status": "active", "…": "see Card object" } ],
"cardCount": 1
}The list is not paginated and contains issued cards only, not pending requests. Balances in the list may be slightly stale; use Get balance for a live value.
CLI: fluxa-wallet card list (this agent's cards) or fluxa-wallet card list --global (all cards in the account).
Get a card
/api/v2/cards/{cardId}Bearer agent-vcReturns { "card": { … } } with a refreshed status.
curl https://agentcard.fluxapay.xyz/api/v2/cards/card_7Hq2LmX9pRt4 \
-H "Authorization: Bearer $AGENT_VC"Card object
{
"id": "card_7Hq2LmX9pRt4",
"cardTypeId": "ct_63243cc4f38836aef2c62ca4",
"status": "active",
"brand": "Visa",
"lastFour": "4242",
"expiryMonth": "10",
"expiryYear": "2029",
"remainingAmountUsd": "18.40",
"fundedAmountUsd": "25.00",
"currency": "USD",
"lastBalanceSyncedAt": "2026-10-27T10:12:00.000Z",
"limits": { "perTransactionMaxUsd": "500" },
"cardholder": {
"name": "Alice Smith",
"billingAddress": { "line1": "10 Main Street", "city": "Boston", "state": "MA", "postalCode": "02101", "country": "US" }
},
"policy": "Usage policy text for this card.",
"createdAt": "2026-10-27T10:01:00.000Z"
}| Field | Description |
|---|---|
id | Card ID (card_…). |
cardTypeId | Product ID, or null for older cards whose product is not known. |
status | See Card statuses. |
brand, lastFour, expiryMonth, expiryYear | Display fields. May be null until first revealed. |
remainingAmountUsd | Spendable balance. |
fundedAmountUsd | Amount loaded onto the card. |
lastBalanceSyncedAt | When the balance was last refreshed. |
limits.perTransactionMaxUsd | Per-purchase maximum, if the card has one; otherwise limits is null. |
cardholder | Name and billing address on the card, if any. Use these at checkout. |
policy | Plain-text usage policy for this card, if any. |
Card statuses
status | Meaning |
|---|---|
active | Usable. Can be recharged and withdrawn from. |
pending | Being activated. Not usable yet. |
frozen | Temporarily not usable. |
blocked | Not usable. Contact support. |
canceled | Permanently closed. |
failed | Issuance did not complete. |
Treat any other value as not usable and check again later.
Get balance
/api/v2/cards/{cardId}/balanceBearer agent-vcFetches the live balance.
curl https://agentcard.fluxapay.xyz/api/v2/cards/card_7Hq2LmX9pRt4/balance \
-H "Authorization: Bearer $AGENT_VC"{
"card": { "id": "card_7Hq2LmX9pRt4", "…": "see Card object" },
"balance": {
"fundedAmountUsd": "25.00",
"remainingAmountUsd": "18.40",
"currency": "USD",
"status": "active",
"lastBalanceSyncedAt": "2026-10-27T10:12:00.000Z"
}
}If the live balance cannot be fetched, this endpoint returns a 5xx error instead of a stale value. Retry later.
CLI: fluxa-wallet card balance --id card_7Hq2LmX9pRt4
Reveal card details
/api/v2/cards/{cardId}/detailsBearer agent-vcReturns the full card number, CVV and expiry. Call it only when you are about to pay, and never log the result.
curl -X POST https://agentcard.fluxapay.xyz/api/v2/cards/card_7Hq2LmX9pRt4/details \
-H "Authorization: Bearer $AGENT_VC"{
"success": true,
"details": {
"cardId": "card_7Hq2LmX9pRt4",
"cardStatus": "active",
"pan": "4242424242424242",
"cvv": "123",
"expiryMonth": "10",
"expiryYear": "2029",
"holderName": "Alice Smith",
"billingAddress": { "…": "…" }
}
}Check cardStatus is active before using the card. Every reveal is recorded on the account.
CLI: fluxa-wallet card details --id card_7Hq2LmX9pRt4
Errors
| Status | code | What to do |
|---|---|---|
| 400 | card_type_selector_required, card_type_selector_invalid | Send exactly one valid selector. |
| 400 | invalid_amount, card_type_amount_out_of_range | Use an amount within the range in the error message / product limits. |
| 400 | card_balance_limit_exceeded | The amount would exceed the per-card balance cap. Use a smaller amount. |
| 400 | invalid_card_id | Use a card_… ID. |
| 400 | missing_pending_request_id, missing_payment_payload | Send both fields to /cards/complete. |
| 403 | vip_whitelist_required | The user must apply for this product in FluxA Wallet (details.applicationUrl when present). Retry after approval. Do not pay. |
| 404 | card_type_not_found, card_not_found, pending_request_not_found | Check the ID. |
| 409 | card_type_ambiguous, card_type_unavailable | Choose a different product. |
| 409 | card_limit_reached | The account has the maximum number of cards. |
| 409 | cardholder_required, cardholder_not_approved, bank_holder_action_required | Complete or fix the cardholder profile. |
| 409 | pending_request_invalid_status | The request is no longer payable. Get the request to see its status. |
| 410 | pending_request_expired | The payment window passed. Start a new request. |
| 429 | daily_card_limit_reached | New cards are temporarily limited. Try again tomorrow. |
| 503 | card_access_unavailable, card_issuance_paused, card_limits_unavailable, card_types_unavailable | Temporary. Retry later; nothing was charged. |
See Errors for the full list.
