Skip to content

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:

  1. Initiate — choose a product and initial load. AgentCard returns a pendingRequestId and, once the request is payable, an x402 paymentRequest for the load plus the issuance fee.
  2. Pay and complete — sign the paymentRequest with 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:

bash
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 ​

POST/api/v2/cards/initiateBearer agent-vc
bash
curl -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"
  }'
FieldTypeRequiredDescription
cardTypeId | binId | binstringexactly oneProduct selector. See Selecting a product.
amountUsdstringyesInitial 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):

json
{
  "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):

json
{
  "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"
}
FieldDescription
pendingRequestIdKeep this. Every retry, poll and completion uses the same ID.
statusSee Request statuses.
amountUsd, feeUsd, totalUsdLoad, fee and the total you will pay (totalUsd = amountUsd + feeUsd).
paymentRequestx402 payment requirements. Present only when status is pending_payment.
expiresAtPay 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 fieldValue
mandateIdYour signed mandate
scheme, networkaccepts[0].scheme, accepts[0].network
amountaccepts[0].maxAmountRequired
currencyUSDC
assetAddressaccepts[0].asset
payToaccepts[0].payTo
resource, hostaccepts[0].resource and its host
tokenName, tokenVersionaccepts[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 ​

POST/api/v2/cards/completeBearer agent-vc
bash
curl -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>"
  }'
FieldTypeRequired
pendingRequestIdstringyes
paymentPayloadB64stringyes

Response 201 — card issued:

json
{
  "success": true,
  "card": { "id": "card_7Hq2LmX9pRt4", "status": "active", "…": "see Card object" }
}

Response 202 — payment received, card still being issued:

json
{
  "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 ​

GET/api/v2/cards/requests/{pendingRequestId}Bearer agent-vc

Returns the current state of an issuance or recharge request.

bash
curl https://agentcard.fluxapay.xyz/api/v2/cards/requests/2b0f8a3e-5c1d-4f7a-9e2b-6d4c8a1f0e37 \
  -H "Authorization: Bearer $AGENT_VC"
json
{
  "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" }
}
FieldDescription
requestTypeissue or recharge.
cardIdFor recharges, the card being recharged. null for issuance.
paymentRequestPresent while status is pending_payment.
cardThe resulting card, once completed.
nextActionPresent on some action_required responses.

Request statuses ​

statusMeaningWhat to do
pending_cardholderWaiting for cardholder review. No payment requested yet.Poll this endpoint.
pending_paymentPayable. paymentRequest is included.Sign and complete before expiresAt.
completedDone. card is included.Use the card.
action_requiredThe cardholder details need attention.Check GET /cardholders/get and ask the user to fix their details.
expiredNot paid in time. No money was taken.Start a new request.
failedThe request could not be completed.Start a new request if the user still wants a card.
refundedPayment was returned to the payer.Start a new request if needed.
any other valueProcessing (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 ​

GET/api/v2/cardsBearer agent-vc
bash
# Cards issued by this agent
curl "https://agentcard.fluxapay.xyz/api/v2/cards?issuedBy=me" \
  -H "Authorization: Bearer $AGENT_VC"
QueryDescription
issuedBy=meOnly cards issued by the calling agent. Omit to list every card in the linked account.
json
{
  "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 ​

GET/api/v2/cards/{cardId}Bearer agent-vc

Returns { "card": { … } } with a refreshed status.

bash
curl https://agentcard.fluxapay.xyz/api/v2/cards/card_7Hq2LmX9pRt4 \
  -H "Authorization: Bearer $AGENT_VC"

Card object ​

json
{
  "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"
}
FieldDescription
idCard ID (card_…).
cardTypeIdProduct ID, or null for older cards whose product is not known.
statusSee Card statuses.
brand, lastFour, expiryMonth, expiryYearDisplay fields. May be null until first revealed.
remainingAmountUsdSpendable balance.
fundedAmountUsdAmount loaded onto the card.
lastBalanceSyncedAtWhen the balance was last refreshed.
limits.perTransactionMaxUsdPer-purchase maximum, if the card has one; otherwise limits is null.
cardholderName and billing address on the card, if any. Use these at checkout.
policyPlain-text usage policy for this card, if any.

Card statuses ​

statusMeaning
activeUsable. Can be recharged and withdrawn from.
pendingBeing activated. Not usable yet.
frozenTemporarily not usable.
blockedNot usable. Contact support.
canceledPermanently closed.
failedIssuance did not complete.

Treat any other value as not usable and check again later.


Get balance ​

GET/api/v2/cards/{cardId}/balanceBearer agent-vc

Fetches the live balance.

bash
curl https://agentcard.fluxapay.xyz/api/v2/cards/card_7Hq2LmX9pRt4/balance \
  -H "Authorization: Bearer $AGENT_VC"
json
{
  "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 ​

POST/api/v2/cards/{cardId}/detailsBearer agent-vc

Returns the full card number, CVV and expiry. Call it only when you are about to pay, and never log the result.

bash
curl -X POST https://agentcard.fluxapay.xyz/api/v2/cards/card_7Hq2LmX9pRt4/details \
  -H "Authorization: Bearer $AGENT_VC"
json
{
  "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 ​

StatuscodeWhat to do
400card_type_selector_required, card_type_selector_invalidSend exactly one valid selector.
400invalid_amount, card_type_amount_out_of_rangeUse an amount within the range in the error message / product limits.
400card_balance_limit_exceededThe amount would exceed the per-card balance cap. Use a smaller amount.
400invalid_card_idUse a card_… ID.
400missing_pending_request_id, missing_payment_payloadSend both fields to /cards/complete.
403vip_whitelist_requiredThe user must apply for this product in FluxA Wallet (details.applicationUrl when present). Retry after approval. Do not pay.
404card_type_not_found, card_not_found, pending_request_not_foundCheck the ID.
409card_type_ambiguous, card_type_unavailableChoose a different product.
409card_limit_reachedThe account has the maximum number of cards.
409cardholder_required, cardholder_not_approved, bank_holder_action_requiredComplete or fix the cardholder profile.
409pending_request_invalid_statusThe request is no longer payable. Get the request to see its status.
410pending_request_expiredThe payment window passed. Start a new request.
429daily_card_limit_reachedNew cards are temporarily limited. Try again tomorrow.
503card_access_unavailable, card_issuance_paused, card_limits_unavailable, card_types_unavailableTemporary. Retry later; nothing was charged.

See Errors for the full list.

Released under the MIT License.