API Keys & Auth
Model calls, Units, Token Plans and programmatic API publishing on FluxA AgentMarket authenticate with a bearer credential. Two kinds are accepted:
| Credential | Looks like | Lifetime | Use it for |
|---|---|---|---|
| API key | fxa_live_... | Until revoked | Servers, SDKs, coding tools. Can carry a spend cap |
| Agent VC | A JWT (eyJ...) | About 5 minutes | Agents using FluxA Agent Wallet. Nothing to store |
Authorization: Bearer fxa_live_...
Authorization: Bearer eyJhbGciOi...Both resolve to the same AgentMarket account, so they see the same Units balance and Token Plans.
Paid APIs under /api/{slug} do not use these credentials. They are paid per call with x402; see Call Paid APIs.
Agent VC
Mint one from the agent's wallet identity. The audience must be exactly fluxa-wallet-service.
VC=$(fluxa-wallet agent-vc --audience fluxa-wallet-service \
--challenge wallet-user-info-lookup --ttl 300 | jq -r .data.vc)A VC lasts five minutes. Mint a fresh one per run, and re-mint during long polling loops. The fluxa-wallet market … commands mint VCs for you automatically.
Create a key on the website
Sign in at agentmarket.fluxapay.xyz and open Console > API Keys (/keys). The raw key is shown once.
Manage keys programmatically
These endpoints accept only an Agent VC. An fxa_live_ key is refused with 403, so a leaked key can never mint more keys or revoke others.
GET https://router.fluxapay.xyz/llm/keys
{
"keys": [
{
"id": "0b6f6a1e-3c1d-4b8e-9b5a-2f7d0c1e9a44",
"name": "ci",
"keyPrefix": "fxa_live_ab12",
"spendCapCredits": 5000000,
"spentCredits": 12500,
"lastUsedAt": "2026-10-27T08:15:00Z",
"revokedAt": null,
"createdAt": "2026-10-20T10:00:00Z"
}
]
}Only the prefix of each key is returned, never the key itself.
POST https://router.fluxapay.xyz/llm/keys
{ "name": "ci", "spendCapCredits": 5000000 }Both fields are optional. Returns 201:
{
"id": "0b6f6a1e-3c1d-4b8e-9b5a-2f7d0c1e9a44",
"name": "ci",
"keyPrefix": "fxa_live_ab12",
"spendCapCredits": 5000000,
"rawKey": "fxa_live_..."
}rawKey is returned once. Store it immediately.
PATCH https://router.fluxapay.xyz/llm/keys/{id}
Change the name and/or spend cap. Send at least one field. spendCapCredits: null (or 0) removes the cap.
{ "spendCapCredits": 10000000 }Returns the updated key (same fields as the list, without lastUsedAt/createdAt). Changes apply on the next call.
DELETE https://router.fluxapay.xyz/llm/keys/{id}
Revokes the key. It stops working on its next call. Irreversible. Returns { "success": true }.
To rotate a key: create the new key, switch your clients to it, then revoke the old one.
Spend caps
spendCapCredits and spentCredits are in Units (1 Unit = $0.00001, so 5000000 = $50). A cap limits model calls made with that key only. When spentCredits reaches the cap, model calls with that key return 403 with error: "spend_cap_exceeded". Balance reads are not limited by caps.
Errors
| Status | Meaning |
|---|---|
400 | Body is not JSON, a field has the wrong type, or nothing to update |
401 | Missing, invalid or expired credential. hint says what to fix |
403 | Called with an fxa_live_ key instead of an Agent VC, or the account is suspended |
404 | Key not found |
503 | The sign-in service is temporarily unavailable. Retry shortly with the same VC |
{ "error": "Unauthorized", "hint": "Agent VC rejected (expired or unverifiable). Mint a fresh VC and retry." }CLI
fluxa-wallet market keys # list
fluxa-wallet market keys create --name ci --cap <amount>
fluxa-wallet market keys update <id> --cap <amount> # --cap 0 clears the cap
fluxa-wallet market keys revoke <id>
export FLUXA_KEY=fxa_live_... # other market commands then use this keyWARNING
The CLI help labels --cap as Monetize Credits, but the value is passed through unchanged and the server counts it in Units. Pass the cap in Units (for example --cap 5000000 for $50).
See CLI: AgentMarket.
