Pay with x402 (for agents)
Fluence accepts balance top-ups over the x402 protocol: an HTTP client pays USDC on Base and the amount is credited to a Fluence balance in the same request. No signup, email or console visit is needed — the paying wallet is the account. This is the shortest path for an AI agent or a script to get compute on Fluence:
- Top up the balance with USDC through x402. The first payment from a wallet creates a Fluence account bound to that wallet.
- Sign in with the same wallet (Sign-In with Ethereum) to get an access token.
- Call the Fluence API with that token.
Requirements
- An EVM wallet controlled by a private key (an externally owned account). Smart-contract wallets cannot sign in.
- USDC on Base mainnet: network
eip155:8453, token0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913. No ETH is needed for gas — the x402 facilitator submits the transfer. - An x402 v2 client. The
@x402/*packages (@x402/fetch,@x402/axios, with@x402/evmfor EVM payments) speak v2. The unscopedx402-fetchandx402-axiospackages are the older v1 line and cannot read the Fluence payment challenge.
Limits
| Parameter | Value |
|---|---|
| Minimum top-up | 0.50 USD |
| Maximum top-up | 1000 USD per request |
| Precision | Whole cents (at most two decimal places) |
1 USDC is credited as 1 USD.
Endpoints
Base URL: https://api.fluence.dev
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /v2/x402/payment-info?amountUsd=N | None | Returns the x402 payment challenge for N USD without paying |
POST | /v2/x402/top-up?amountUsd=N | Optional | Paid endpoint: answers 402 Payment Required without a payment, settles and credits N USD with one |
GET | /v1/auth/siwe/nonce | None | Issues a single-use sign-in nonce |
POST | /v1/auth/siwe | None | Exchanges a signed Sign-In with Ethereum message for an access token |
For complete request and response schemas, see the API reference.
Step 1: Top up
Wrap fetch with an x402 client and call the top-up endpoint. The client handles the 402 → sign → retry exchange.
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);
const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
});
const response = await fetchWithPayment(
"https://api.fluence.dev/v2/x402/top-up?amountUsd=10",
{ method: "POST" },
);
console.log(response.status, await response.json());
A successful top-up returns 200 with a JSON body carrying amountUsd, network, asset, transaction (the Base transaction hash) and payer. The PAYMENT-RESPONSE header carries the x402 settlement response.
Other responses:
| Status | Meaning | What to do |
|---|---|---|
400 | Amount out of range or with more than two decimal places, or a malformed payment | Fix the request |
402 | Payment required, or the payment was rejected (for example, not enough USDC). The error field of the challenge says why | Fix the cause and pay again |
409 | The payment was submitted and is under review | Do not sign a new payment — the transfer may already be on chain. Contact support with the payer address |
503 | Top-ups are unavailable, or the payment did not reach the facilitator. Nothing was charged | Retry later |
Already have a Fluence account? Send your API key in the X-API-KEY header (or an access token in Authorization: Bearer) with the top-up request, and the amount is credited to that account instead of a wallet account.
Step 2: Sign in with the wallet
Request a nonce, sign a Sign-In with Ethereum message with the wallet that paid, and exchange it for an access token.
import { createSiweMessage } from "viem/siwe";
const { nonce } = await (await fetch("https://api.fluence.dev/v1/auth/siwe/nonce")).json();
const message = createSiweMessage({
domain: "api.fluence.dev",
address: account.address,
uri: "https://api.fluence.dev",
version: "1",
chainId: 8453,
nonce,
});
const signature = await account.signMessage({ message });
const login = await fetch("https://api.fluence.dev/v1/auth/siwe", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message, signature }),
});
const { accessToken, refreshToken } = await login.json();
- The message
domainmust be exactlyapi.fluence.dev; any other domain is rejected. - A nonce works once and expires 10 minutes after it is issued (see
expiresAtin the nonce response). - Send the message exactly as signed.
Step 3: Use the API
Send the access token as a bearer token. For example, check the balance:
curl https://api.fluence.dev/v2/users/balances \
-H "Authorization: Bearer <ACCESS_TOKEN>"
Access tokens are short-lived. When one expires, sign in again (step 2). A long-running agent can instead create an API key once with POST /v1/api_keys (a name, the scopes it needs and an expiresAt time) and send it in the X-API-KEY header, as described in the API introduction.
To rent compute with the funded balance, continue with CPU Cloud or GPU Cloud.