X402 Payments

Neura uses the Coinbase X402 protocol to protect every monetized endpoint. Requests are served once the client proves payment by presenting the signed headers defined in the Coinbase X402 welcome guide. This page explains how the middleware behaves and provides sample client implementations.

High level flow

  1. Discovery request Call any monetized endpoint without payment headers. The middleware replies with HTTP 402 Payment Required.

  2. Inspect invoice The 402 response includes headers such as:

    • X-402-Invoice – base64 encoded invoice payload.

    • X-402-Network – settlement network (solana or base).

    • X-402-Amount – required amount in the target network’s currency units.

    • X-402-Facilitator – facilitator URL (https://facilitator.payai.network in Neura’s default configuration).

  3. Pay the invoice Use an X402 compatible wallet or SDK to settle the invoice on the declared network. The invoice memo ties the payment to the HTTP request.

  4. Replay with proof Resend the HTTP request with the headers described in the Coinbase guide (for example X-402-Payment-Proof, X-402-Invoice, X-402-Version). The middleware verifies the payment and forwards the request to the handler.

  5. Receive response A successful request returns HTTP 200 with the Neura JSON envelope.

Network routing

Prefix
Network
Notes

/

Solana

Default behavior if no prefix is present. Uses SOLANA_ADDRESS.

/solana

Solana

Explicit Solana routing for clients that separate their integration.

/base

Base

Uses BASE_ADDRESS. Prices are identical to Solana.

The middleware automatically selects the appropriate pay-to address based on the prefix.

Price sheet (per request)

Resource
Price
Applies to

Tokens, Balances, Networks, Bars, Launchpads

0.0004 USD

Every monetized route under /, /solana, /base.

Health, Resilience

Free

/health, /health/resilience.

Client examples

The snippets below mirror patterns from the Coinbase documentation and demonstrate the complete 402 round trip.

TypeScript with @coinbase/x402

import { X402Client } from "@coinbase/x402";
import fetch from "node-fetch";

const client = new X402Client({
  apiKeyName: process.env.CDP_API_KEY_ID!,
  privateKey: process.env.CDP_API_KEY_SECRET!,
  facilitatorUrl: "https://facilitator.payai.network",
});

async function getToken(address: string, networkId: number) {
  const baseUrl = "https://api.neura.xyz";
  const path = `/token/${address}/${networkId}`;

  // 1. Discovery request (expect 402)
  const discovery = await fetch(`${baseUrl}${path}`);
  if (discovery.status !== 402) {
    throw new Error(`Unexpected status ${discovery.status}`);
  }

  const invoice = discovery.headers.get("x-402-invoice");
  if (!invoice) {
    throw new Error("Missing X-402 invoice header");
  }

  // 2. Pay invoice via Coinbase helper
  const settlement = await client.settleInvoice({
    invoice,
    network: discovery.headers.get("x-402-network") ?? "solana",
  });

  // 3. Replay with payment proof headers
  const proofHeaders = client.buildProofHeaders({
    invoice,
    settlement,
    method: "GET",
    url: `${baseUrl}${path}`,
  });

  const paidResponse = await fetch(`${baseUrl}${path}`, {
    method: "GET",
    headers: proofHeaders,
  });

  if (!paidResponse.ok) {
    const body = await paidResponse.text();
    throw new Error(`Paid request failed: ${paidResponse.status} ${body}`);
  }

  return paidResponse.json();
}

getToken("0xA0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", 1)
  .then((data) => console.log(data))
  .catch((err) => console.error(err));

Python with coinbase_x402

import os
import requests
from coinbase_x402 import Client

client = Client(
    api_key_name=os.environ["CDP_API_KEY_ID"],
    private_key=os.environ["CDP_API_KEY_SECRET"],
    facilitator_url="https://facilitator.payai.network",
)

base_url = "https://api.neura.xyz"
path = "/balances"

discovery = requests.post(f"{base_url}{path}", json={
    "walletAddress": "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6",
    "networks": [1, 137]
})

if discovery.status_code != 402:
    raise RuntimeError(f"Expected 402, got {discovery.status_code}")

invoice = discovery.headers["x-402-invoice"]
network = discovery.headers.get("x-402-network", "solana")

settlement = client.settle_invoice(invoice=invoice, network=network)

proof_headers = client.build_proof_headers(
    invoice=invoice,
    settlement=settlement,
    method="POST",
    url=f"{base_url}{path}",
    body='{"walletAddress":"0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6","networks":[1,137]}'
)

paid = requests.post(
    f"{base_url}{path}",
    json={
        "walletAddress": "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6",
        "networks": [1, 137]
    },
    headers=proof_headers,
)

paid.raise_for_status()
print(paid.json())

Both examples rely on helper methods described in the Coinbase documentation. If you are not using the official SDKs, follow the signing rules in the guide to generate the required headers manually.

Common troubleshooting tips

Symptom
Checklist

Receiving repeated 402 responses

Ensure the payment was committed on the correct network, confirm the memo matches the invoice, and verify you are replaying the exact same HTTP method, URL, and body.

429 after payment

The Neura API enforces rate limits even after successful payment. Retry after the number of seconds specified in the retry-after field.

400 level errors

Review the endpoint specific validation guidance in the Endpoint Catalog. Payment proof was accepted; the issue lies with the payload.

Facilitator rejection

Validate CDP_API_KEY_ID and CDP_API_KEY_SECRET, and confirm the facilitator URL from the invoice matches the one hitting your SDK.

Additional resources

Last updated