# FluxA x402 Payment Guide

How an AI agent pays for any FluxA API. Read this once — it applies to every API on the platform. `<API_BASE_URL>` below stands for the API's proxy URL from its integration guide.

A full worked example, with the real output of every step and a complete script: https://github.com/FluxA-Agent-Payment/FluxA-AI-Wallet-MCP/blob/main/skills/fluxa-agent-wallet/X402-PAYMENT.md

## Find an API

Pick one way, then pay as below.

- **By use case**, when you know what you need, e.g. "Douyin comments" or "work email for a person":

  ```bash
  curl "https://agentmarket.fluxapay.xyz/api/discover?by=use-case&q=douyin"
  ```

  Each use case lists its providers and a skill.md with every endpoint for it, across providers.

- **By provider**, when the user names a provider, or you need all of one provider's API:

  ```bash
  curl "https://agentmarket.fluxapay.xyz/api/discover?q=socialdatax"
  ```

  Each provider has its own skill.md.

## Choose how to pay — before the first paid call

Two rails exist. They debit different accounts, and both charge the same list price
(1 USDC = $1 = 100,000 Units of Balance). Which account to spend from is the user's decision.

| Rail | Debits | Credential |
|------|--------|------------|
| Wallet USDC | the user's FluxA wallet, on-chain | signed USDC mandate |
| Balance | the user's AgentMarket Balance | `fxa_live_` API key or Agent VC |

Every API on AgentMarket takes both rails, so either one can pay any task.

### If the user already named a rail

Use it. Check only that it can cover the total — signed-mandate remaining, or Balance
available — and if it cannot, say by how much and stop. Do not switch rails on your own.

### Otherwise, price the task on both rails

After discovery, and **before** creating a mandate or calling a paid endpoint, report the
endpoints you intend to call and the total on each rail. Then **stop and wait for the user
to choose.** For example:

```
Task: 4 endpoints, $0.14 total

A) From the Balance — 14,000 Units ($0.14). Balance available: $3.20
B) In USDC          — $0.14. Signed mandate remaining: 0.879 USDC

Which rail should I use?
```

An approval of the amount is **not** an approval of the rail. Do not infer the rail from
"a signed mandate already exists", "the Balance is large enough", or how the last call was
paid. If the user has not said which rail to use, ask.

If the chosen rail cannot pay — no mandate, no key or Agent VC, funds short — say exactly
what is missing and where to get it (an API key from `https://agentmarket.fluxapay.xyz/keys`, or mint an Agent VC), then
stop. Never fall back to the other rail on your own.

## Setup — Install FluxA Wallet CLI

```bash
npm install -g @fluxa-pay/fluxa-wallet
```

Or use without installing:

```bash
npx fluxa-wallet <command> [options]
```

All commands output JSON: `{ "success": true, "data": { ... } }`

## Register Agent

```bash
fluxa-wallet init --name "<YOUR_AGENT_NAME>" --client "<YOUR_CLIENT>"
```

The CLI handles JWT storage and automatic refresh. Verify status:

```bash
fluxa-wallet status
```

## x402 v3 Intent Mandate Payment

x402 v3 uses **intent mandates**: the user pre-approves a spending plan (budget + time window), then the agent can make autonomous payments within those limits. The user only needs to approve once.

### Step 1 — Choose Payment Method

Pay with the FluxA Wallet in USDC on Base: don't ask the user to choose a payment method. Use a FluxA API key only if the user already gave you one.

Cold start: if `fluxa-wallet` is missing, install it and run `init` (see Setup above) without asking. If `fluxa-wallet check-wallet` says `linked: false`, run `fluxa-wallet link-wallet`, send the user its `linkUrl` with the task's cost, then re-run `check-wallet` every few seconds until `linked` is `true` (up to 10 minutes) and continue to Step 2. Don't ask the user to reply "done".

- **FluxA Wallet (USDC on Base)**: `--currency USDC`, `--amount` in atomic units (6 decimals, e.g., `1000000` = 1 USDC). Continue to Step 2.
- **FluxA API key**: no mandate needed. Send `Authorization: Bearer <key>` on the call and it is paid from the user's AgentMarket Balance. If the balance is too low the API answers 402 with `insufficient_balance`; top up, or pay that call with the wallet. Skip to Step 5.

### Step 2 — Reuse or Create a Mandate

First run `fluxa-wallet mandates`. If a mandate is `signed`, not expired, in USDC, and has enough `remaining` for this task, use it, send no link, and skip to Step 5.

Otherwise request a budget for **at least 100 calls** at the API's price, valid 7 days, so later tasks run with no new link. Don't request only enough for the current task.

```bash
fluxa-wallet mandate-create \
  --desc "Spend up to <BUDGET> for <DESCRIPTION> valid for 7 days" \
  --amount <BUDGET_IN_UNITS> \
  --seconds 604800 \
  --currency USDC
```

| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| `--desc` | Yes | — | Human-readable spending plan description |
| `--amount` | Yes | — | Budget limit in USDC atomic units |
| `--seconds` | No | `28800` (8h) | Validity duration in seconds (use `604800`, 7 days) |
| `--currency` | No | `USDC` | `USDC` |

Response includes `mandateId` and `authorizationUrl` (TTL: 10 minutes).

### Step 3 — Send the Link

Don't ask "may I spend?" first: the user's signature on the link is the approval. Send exactly this, and nothing else:

```
{Provider} charges ${unit_price} per {unit}. This task needs about ${estimate}.
Approve a ${budget} budget (valid 7 days): {authorizationUrl}
I'll continue as soon as you approve.
```

Make the URL clickable, and run `open "<authorizationUrl>"` if you can open a browser for the user. Don't quote this guide or explain FluxA policy unless asked.

### Step 4 — Wait Until Signed

Right after sending the link, in the same turn, wait for the signature. **Never ask the user to reply "done" or "signed".**

```bash
fluxa-wallet mandate-status --id <MANDATE_ID> --wait 100
```

It blocks until the mandate is `signed`, `rejected` or `expired` (exit code 0 only when signed). If it ends with `"code": "wait_timeout"`, run it again, up to 10 minutes in total. If the link expires, tell the user and offer a fresh one. Needs `@fluxa-pay/fluxa-wallet` 0.5.4 or newer.

The two commands name the mandate differently:

| Command | Flag for the mandate id |
|---------|-------------------------|
| `fluxa-wallet mandate-status` | `--id` |
| `fluxa-wallet x402-v3` | `--mandate` |

### Step 5 — Call the API

```bash
curl <API_BASE_URL>/<endpoint>
# optional: add -H "X-Agent-ID: <your-agent-id>" to attribute the call to your agent
```

If the API returns HTTP 402, continue to Step 6.

### Step 6 — Make x402 v3 Payment

The 402 response contains an `accepts` array with entries for different payment networks.

Pass the **full** 402 response body as the payload. Do not edit it. The wallet picks the `base` (USDC) entry.

```bash
fluxa-wallet x402-v3 \
  --mandate <MANDATE_ID> \
  --payload "$RESPONSE_402"
```

Response includes `xPaymentB64` (the payment token).

### Step 7 — Retry with X-Payment Header

```bash
curl -H "X-Payment: <xPaymentB64>" <API_BASE_URL>/<endpoint>
```

Return the API response to the user, with what was actually spent (the sum of the calls made, not the budget).

## Optional Tracking Headers

These headers are optional — include them to attribute and group your API usage. (The exceptions are configs marked `require_agent_auth` and MCP `tools/call` requests, which do require `X-Agent-ID`.)

| Header | Required | Value | Purpose |
|--------|----------|-------|---------|
| `X-Agent-ID` | Optional | Your agent ID from `fluxa-wallet status` → `agent_id` | Identifies which agent made the request |
| `X-Skill-Name` | Optional | Name of the skill making this call | Links skill to API usage |
| `X-Task-Id` | Optional | Unique ID for the current task/conversation | Groups API calls per task |

Example:
```bash
curl -H "X-Agent-ID: <your-agent-id>" -H "X-Skill-Name: my-skill" -H "X-Task-Id: task-abc123" <API_BASE_URL>/<endpoint>
```

**Note:** Run `fluxa-wallet init` to set up your wallet (needed to sign mandates). `fluxa-wallet status` gives your `agent_id` if you choose to send `X-Agent-ID`.

## Amount Reference

| USDC | Mandate amount (USDC atomic) |
|------|------------------------------|
| 0.01 | `10000` |
| 0.10 | `100000` |
| 1.00 | `1000000` |

## Opening Links for User

Send authorization links as complete, clickable URLs, in the same message as the cost they approve. If you can open a browser for the user, also run `open "<URL>"`. Don't ask whether to open a link, and don't ask the user to confirm they signed: wait with `mandate-status --wait`.

## Error Handling

| Error | Meaning | Action |
|-------|---------|--------|
| `mandate_not_signed` | User hasn't signed yet | Wait with `mandate-status --id <id> --wait 100` (Step 4) |
| `mandate_expired` | Time window passed | Create a new mandate |
| `mandate_budget_exceeded` | Budget too low | Create a new mandate sized as in Step 2 and send the Step 3 message |
| `mandate_inactive` with `currency_mismatch` | Your mandate is in a currency this API does not accept | Create a new mandate in one of the currencies listed in the 402's `accepts` |
| `agent_not_registered` | No Agent ID | Run `fluxa-wallet init` first |
| `Invalid payload: missing accepts array` | Incomplete 402 payload | Pass the full 402 response JSON |

---

- Platform overview: https://agentmarket.fluxapay.xyz/skill.md
- Discover APIs: `curl https://agentmarket.fluxapay.xyz/api/discover`