Skip to content

Charging for your agent with x402

Copy page

This page is for the seller: you have built an assistant, published it as a release, and want software agents to pay for each call. If you are the caller paying for a tool, see x402 Payments instead.

x402 revives the HTTP 402 Payment Required status. A caller that hasn't paid gets a 402 describing the price and the wallet to pay. The caller's wallet signs a USDC transfer, retries the request, and is served.

  • A Divinci workspace with a published release.
  • A wallet address on Base that you control. Double-check it: USDC sent to a mistyped address cannot be recovered.

You do not need a Coinbase, Stripe or Cloudflare account. Payments are verified and settled by an x402 facilitator that Divinci calls for you (x402.org on base-sepolia), and the facilitator pays the gas, so callers pay only your price.

x402 is attached to an API key, not to the release:

  • Callers must hold the key. Without it they get 401, not 402.
  • A key with a payment rail can call only POST /api/v1/chat/completions. Every other endpoint answers 403 (PAYMENT_RAIL_KEY_SCOPE), so a paying caller cannot reach your other data or run un-billed generation.
  • The key's releaseId is the default release. A caller can still name another release in your workspace in the request body.
  • The key's payment rail is Crypto (x402) (paymentRail: "divinci-x402"). Keys with no rail are served free.
  • Price and payee are per workspace, shared by every x402 key in it.

Today, charging applies to POST /api/v1/chat/completions.

  1. Publish your release as usual.

  2. Set where you get paid, and activate. In the web app, open your workspace, go to Embed → Payments, choose the network (base-sepolia), paste your wallet address, set a price and the status Active, then Save. Or use the API. Each call replaces the whole settlement, so always send every field. Authenticate as a workspace member who can edit configuration.

    Terminal window
    curl -X POST "https://api.divinci.app/white-label/$WHITELABEL_ID/payment-settlement" \
    -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
    -d '{
    "railId": "divinci-x402",
    "status": "active",
    "network": "base-sepolia",
    "payTo": "0xYourWalletAddress",
    "priceUsdOverride": 0.02
    }'

    priceUsdOverride is USD per request. Omit it for the platform default (currently $0.01). Use 0 for free, or at least 0.000001; smaller amounts round to zero on-chain and are rejected. Activation requires payTo and network.

  3. Create the key, after the settlement is active. Key creation is refused until it is: you get 409 ("Activate a payment settlement for this workspace before creating a key that charges callers."). In the web key form you can pick the release to pin and set the payment rail to Crypto (x402). The web form does not show the secret on create, so to get a key you can hand out in one step, use the API:

    Terminal window
    curl -X POST "https://api.divinci.app/api/v1/workspaces/$WHITELABEL_ID/api-keys" \
    -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
    -d '{
    "name": "paid-agent",
    "releaseId": "YOUR_RELEASE_ID",
    "paymentRail": "divinci-x402",
    "permissions": ["transcript:write"]
    }'

    The response holds the key in secret. It is shown once, so store it now; if you lose it, rotate the key to get a new one.

    Settlement has to be active first (step 2), because a key that cannot charge is never served for free: it is refused at creation, and a key whose settlement later becomes unusable answers 503.

  4. Test it. Call the endpoint with the key and no payment:

    Terminal window
    curl -i -X POST "https://api.divinci.app/api/v1/chat/completions" \
    -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
    -d '{ "messages": [{ "role": "user", "content": "hello" }] }'

    You should get a 402 whose accepts[0].payTo is your address. Check it character by character before going live.

{
"x402Version": 1,
"error": "X-PAYMENT header is required",
"accepts": [{
"scheme": "exact",
"network": "base-sepolia",
"maxAmountRequired": "20000",
"asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"payTo": "0xYourWalletAddress",
"resource": "https://api.divinci.app/…",
"description": "Divinci chat completion",
"mimeType": "application/json",
"maxTimeoutSeconds": 60,
"extra": { "name": "USDC", "version": "2" }
}]
}

maxAmountRequired is in USDC atomic units (6 decimals), so 20000 is $0.02. There is no public price list; a caller learns the price from this 402. The server SDK pays it automatically when autopay is on (default cap $1 per call).

  • Draft or missing settlement. A key cannot be created, and an existing key answers 503 (payment_rail_unavailable) rather than serving for free on your account.
  • Active fails closed. If your settlement becomes unusable, the endpoint returns 503 rather than serving for free on your account.
  • Disabled is the one way to stop charging. Setting the status to Disabled deliberately turns charging off for every x402 key in the workspace, and those keys are then served free. Use it only when you mean it.
  • Replays are rejected. Each signed authorization works once.
  • Payment settles before the answer is generated. If generation then fails, the caller has paid and there is no automatic refund.
  • It is extra revenue, not a discount. Payments do not reduce what your workspace is billed for usage.
  • Stripe settlement. Drafted but cannot be activated.
  • Base mainnet. Not confirmed end to end.
  • Other endpoints. Only chat/completions is charged.