Authentication
AgentCard authenticates agents with a short-lived Agent VC (Verifiable Credential) bound to a challenge issued by AgentCard. You never send your Agent ID login JWT to AgentCard.
The flow has three steps:
- Get a challenge from AgentCard.
- Mint a VC for that challenge and audience from Agent ID.
- Send the VC as a Bearer token on every AgentCard request.
CLI
fluxa-wallet card … commands do this automatically on every call. You only need this page if you call the HTTP API yourself.
1. Get a challenge
/api/v2/auth/challengeNo authentication and no request body.
curl -X POST https://agentcard.fluxapay.xyz/api/v2/auth/challengeResponse 200:
{
"challenge": "chal_3f6c1a52-8a0e-4b8e-9a43-5f1d2a7c9e10",
"expiresAt": "2026-10-27T10:10:00.000Z",
"audience": "<agentcard-audience>"
}| Field | Type | Description |
|---|---|---|
challenge | string | Opaque value to embed in the VC. |
expiresAt | string (ISO 8601) | The challenge is valid for 10 minutes. |
audience | string | The audience to put in the VC. Use the returned value exactly; do not hardcode it. |
2. Mint a VC
Call the Agent ID VC issue endpoint with your login JWT, passing the challenge and audience from step 1:
curl -X POST https://agentid.fluxapay.xyz/agent/vc/issue \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $LOGIN_JWT" \
-d '{
"challenge": "chal_3f6c1a52-8a0e-4b8e-9a43-5f1d2a7c9e10",
"audience": "<agentcard-audience>",
"ttl_seconds": 600
}'The vc field of the response is your AgentCard bearer token. A ttl_seconds of 600 matches the challenge lifetime.
3. Call AgentCard
curl https://agentcard.fluxapay.xyz/api/v2/cards \
-H "Authorization: Bearer $AGENT_VC"- The first time AgentCard sees a challenge, it binds the challenge to your agent. The same VC can be reused by the same agent for further calls until the challenge or the VC expires, whichever comes first.
- When either expires, fetch a new challenge and mint a new VC.
- A challenge cannot be used by a different agent.
Wallet linking
AgentCard acts on behalf of the FluxA account your Agent ID is linked to. All cards, cardholder profiles and limits belong to that account and are shared by every agent linked to it. If your agent is not linked to a wallet, every call returns 403 agent_not_linked. Link the agent first (CLI: fluxa-wallet link-wallet), then retry.
Authentication errors
Errors use the standard error format: { "error": "<message>", "code": "<code>" }.
| Status | code | What to do |
|---|---|---|
| 401 | authorization_required | Send Authorization: Bearer <agent-vc>. |
| 401 | vc_expired | The VC has expired. Get a new challenge and mint a new VC. |
| 403 | vc_challenge_expired | The challenge has expired. Get a new challenge and mint a new VC. |
| 403 | vc_challenge_invalid | The challenge is unknown. Use a challenge from POST /auth/challenge. |
| 403 | vc_challenge_agent_mismatch | The challenge was already used by another agent. Get your own challenge. |
| 403 | vc_challenge_missing | The VC has no challenge. Mint it with the challenge from step 1. |
| 403 | vc_audience_mismatch | The VC audience is wrong. Use the audience returned by POST /auth/challenge. |
| 403 | vc_issuer_mismatch, vc_invalid, vc_wrong_type, vc_sub_missing | The token is not a valid Agent VC. Mint a new one from Agent ID. Do not send the login JWT. |
| 403 | agent_not_linked | Link the agent to a FluxA Wallet, then retry. |
