Skip to content

Mandates ​

A mandate is a spending budget that the user signs once. While it is active, the agent can pay up to the budget, inside the validity window, without asking the user each time.

All endpoints require Authorization: Bearer <agent-jwt>.

A mandate limits two things:

  • Total budget (limitAmount): the most the agent can spend under this mandate.
  • Validity window (validFrom → validUntil): when the mandate can be used.

hostAllowlist and per-transaction limits are stored on the mandate for reference only. They do not restrict payments, so don't rely on them as a safety control.

Currencies ​

currencyAmount unitsNotes
USDC6 decimals (1000000 = 1 USDC)Default.
FLUXA_MONETIZE_CREDITS2 decimals (100 = 1 credit)Credits balance.
XRPdrops (1000000 = 1 XRP)Only where XRP is enabled for the wallet. Otherwise you get unsupported_currency.
CARD_USDcents (12000 = $120.00)Beta. Card mandates for linked-card checkout. They need extra card fields and access to the linked-card feature.

Create intent mandate ​

POST/api/mandates/create-intentBearer agent-jwt

Create a mandate and get a link where the user can review and sign it.

bash
curl -X POST https://walletapi.fluxapay.xyz/api/mandates/create-intent \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -d '{
    "intent": {
      "naturalLanguage": "Pay for WHOIS API calls, up to 5 USDC this month",
      "currency": "USDC",
      "limitAmount": "5000000",
      "validForSeconds": 2592000,
      "category": "api-usage"
    }
  }'

intent fields:

FieldRequiredDescription
naturalLanguageYesPlain-language description the user sees when signing.
limitAmountYesTotal budget as a positive integer string in the currency's atomic units.
validForSecondsYesHow long the mandate is valid, counted from creation. Must be a positive integer of at most 31536000 (1 year). For CARD_USD it defaults to 3600. validUntil is not accepted.
currencyNoSee Currencies. Defaults to USDC.
categoryNoYour own label for grouping.
hostAllowlistNoStored for reference only. Not enforced.

Response (200):

json
{
  "status": "ok",
  "mandateId": "mand_Q2h8x0b1Yc3k9ZpLmN4rTw",
  "authorizationUrl": "https://agentwallet.fluxapay.xyz/onboard/intent?oid=oi_...",
  "expiresAt": "2026-10-27T18:00:00.000Z",
  "agentStatus": "ready"
}
FieldDescription
mandateIdMandate ID (mand_…).
authorizationUrlLink for the user. On one page they link the agent to their wallet (if needed) and sign the mandate.
expiresAtWhen authorizationUrl stops working (about 6 hours). This is not the mandate's validity end. After this time, use the mandate's signUrl from Get mandate by ID, or create a new mandate.
agentStatusready if the agent is already linked to the user's wallet, or needs_wallet_authorization if the user must link it first (the same authorizationUrl handles this).

Show authorizationUrl to the user. Then poll Get mandate by ID until status is signed.

Errors ({ "status": "error", "code", "message" }):

HTTPcodeWhen
400missing_natural_languageintent.naturalLanguage is missing.
400unsupported_currencyThe currency isn't supported or isn't enabled.
400invalid_limit_amountlimitAmount isn't a positive integer string.
400invalid_valid_for_secondsvalidForSeconds is missing, not a positive integer, or over 1 year.
400valid_until_not_supportedYou sent validUntil. Use validForSeconds.
401agent_auth_failedThe agent JWT is missing, invalid or expired. A VC token returns { "error": "wrong_token_type" }.

Mandate status ​

statusMeaningUsable for payments?
pending_signatureAwaiting the user's signature.No. Send the user to signUrl / approvalUrl.
signedSigned by the user.Yes, if it is also enabled, inside its validity window and has budget left.
any other valueNo longer usable (for example revoked or expired).No. Create a new mandate.

validUntil passing does not always change status. Always check the validity window yourself, or use Get eligible mandates, which only returns usable mandates.


Get eligible mandates ​

GET/api/mandates/eligibleBearer agent-jwt

Find the agent's mandates that can pay a given amount right now. The results are signed, enabled, inside their window, in the requested currency, and have at least amount remaining. Use this before calling x402 V3 to pick a mandateId.

bash
curl -G https://walletapi.fluxapay.xyz/api/mandates/eligible \
  -H "Authorization: Bearer $JWT_TOKEN" \
  --data-urlencode "host=x402whois.com" \
  --data-urlencode "amount=10000" \
  --data-urlencode "currency=USDC"

Query parameters:

ParamRequiredDescription
hostYesHost you are paying. It is echoed back in criteria but doesn't filter results.
amountYesPayment amount in atomic units.
currencyNoSee Currencies. Defaults to USDC.

Response:

json
{
  "status": "ok",
  "criteria": { "host": "x402whois.com", "amount": "10000", "currency": "USDC" },
  "eligibleMandates": [
    {
      "mandateId": "mand_Q2h8x0b1Yc3k9ZpLmN4rTw",
      "status": "signed",
      "isEnabled": true,
      "naturalLanguage": "Pay for WHOIS API calls, up to 5 USDC this month",
      "category": "api-usage",
      "currency": "USDC",
      "limitAmount": "5000000",
      "spentAmount": "100000",
      "pendingSpentAmount": "0",
      "remainingAmount": "4900000",
      "validFrom": "2026-10-01T00:00:00.000Z",
      "validUntil": "2026-10-31T00:00:00.000Z",
      "signedAt": "2026-10-01T00:05:00.000Z",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "updatedAt": "2026-10-20T08:00:00.000Z",
      "detailsUrl": "https://agentwallet.fluxapay.xyz/mandates/mand_Q2h8x0b1Yc3k9ZpLmN4rTw",
      "signUrl": "https://agentwallet.fluxapay.xyz/onboard/intent?mandateId=mand_Q2h8x0b1Yc3k9ZpLmN4rTw"
    }
  ]
}

Results are ordered so that the mandate expiring soonest comes first. An empty eligibleMandates array means no mandate can cover this payment. Create a new mandate, or fall back to x402 V1.

remainingAmount = limitAmount − spentAmount − pendingSpentAmount. pendingSpentAmount is budget held by payments that haven't finished yet.

Errors:

HTTPcodeWhen
400missing_host / invalid_amount / unsupported_currencyInvalid query parameters.
401agent_auth_failedInvalid agent JWT.
403 / 404agent_not_authorizedThe agent isn't linked to an authorized FluxA Wallet.

List agent mandates ​

GET/api/mandatesBearer agent-jwt

List the agent's mandates (up to 200, newest first), whatever their status.

bash
curl https://walletapi.fluxapay.xyz/api/mandates \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

json
{
  "status": "ok",
  "mandates": [
    {
      "mandateId": "mand_Q2h8x0b1Yc3k9ZpLmN4rTw",
      "status": "signed",
      "isEnabled": true,
      "naturalLanguage": "Pay for WHOIS API calls, up to 5 USDC this month",
      "category": "api-usage",
      "currency": "USDC",
      "limitAmount": "5000000",
      "spentAmount": "100000",
      "pendingSpentAmount": "0",
      "remainingAmount": "4900000",
      "validFrom": "2026-10-01T00:00:00.000Z",
      "validUntil": "2026-10-31T00:00:00.000Z",
      "signedAt": "2026-10-01T00:05:00.000Z",
      "createdAt": "2026-10-01T00:00:00.000Z",
      "updatedAt": "2026-10-20T08:00:00.000Z"
    }
  ]
}

A 200 response also tells you the agent is linked to an authorized wallet. A 403 with agent_not_authorized means it isn't linked yet.


Get mandate by ID ​

GET/api/mandates/agent/:mandateIdBearer agent-jwt

Get one mandate, including its live remaining budget. The mandate is wrapped in a mandate object.

bash
curl https://walletapi.fluxapay.xyz/api/mandates/agent/mand_Q2h8x0b1Yc3k9ZpLmN4rTw \
  -H "Authorization: Bearer $JWT_TOKEN"
json
{
  "status": "ok",
  "mandate": {
    "mandateId": "mand_Q2h8x0b1Yc3k9ZpLmN4rTw",
    "status": "signed",
    "naturalLanguage": "Pay for WHOIS API calls, up to 5 USDC this month",
    "category": "api-usage",
    "currency": "USDC",
    "limitAmount": "5000000",
    "spentAmount": "100000",
    "pendingSpentAmount": "0",
    "remainingAmount": "4900000",
    "validFrom": "2026-10-01T00:00:00.000Z",
    "validUntil": "2026-10-31T00:00:00.000Z",
    "signedAt": "2026-10-01T00:05:00.000Z",
    "createdAt": "2026-10-01T00:00:00.000Z",
    "updatedAt": "2026-10-20T08:00:00.000Z",
    "signUrl": "https://agentwallet.fluxapay.xyz/onboard/intent?mandateId=mand_Q2h8x0b1Yc3k9ZpLmN4rTw"
  }
}

This response has no isEnabled field. To check that a mandate can actually pay now, use Get eligible mandates. signUrl stays valid while the mandate is awaiting signature, so use it after the original authorizationUrl has expired.

CARD_USD mandates (Beta) return a card-specific shape that includes the merchant and card execution details.

Errors:

HTTPcodeWhen
401agent_auth_failedInvalid agent JWT.
403agent_not_authorizedThe agent isn't linked to an authorized FluxA Wallet.
404mandate_not_foundNo such mandate for this agent.

Released under the MIT License.