XavaInferencesign indocs
docs

x402 pay-per-request

For agents with a Solana wallet and no account: pay each image, video or audio request in USDC.

Available on POST /v1/images/generations, POST /v1/media/generations and the MCP media tools. Chat, embeddings and streaming need an API key.

  1. Send the request with no Authorization header.
  2. We answer 402 Payment Required with a PAYMENT-REQUIRED header (x402 v2): USDC on Solana devnet, the exact amount for this request, and our pay-to address.
  3. Your x402 client signs the USDC transfer and retries the same request with a PAYMENT-SIGNATURE header (X-PAYMENT also works).
  4. We verify and settle the payment, then run the model. The response carries a PAYMENT-RESPONSE receipt with the transaction.
  • The amount is quoted from the request itself: the model and its image count, video seconds and resolution, or audio length. Change the body and you get a new quote.
  • Your split, per call. By default the whole discount is yours: you pay the model's discounted price and nothing is bought back. To send part of it to buybacks, add X-Split: xinf=<bps>,custom=<bps>,discount=<bps> (shares of the discount in basis points, summing to 10000) and X-Split-Token: <mint> when custom is above 0. On the media endpoints a body field "split": {"xinf_bps", "custom_bps", "discount_bps", "custom_mint"} works too; the header wins. xava and xava_bps are still accepted as deprecated aliases of xinf and xinf_bps. The custom token must be eligible in our buyback index. A bad split is a 400, before any payment is asked for.
  • The split is part of the quote: keep it identical on the paid retry, or the payment will not match.
  • Models priced by their output cannot be prepaid (400 x402_unsupported_model); use a key for those.
  • If a paid request fails, you still get the receipt: contact us with the x-request-id.
x402 flow
# 1. call with no key: the answer is 402 + what to pay
curl -i https://zinf.dev/v1/images/generations \
  -H "Content-Type: application/json" \
  -d '{"model":"pruna/p-image","prompt":"a lighthouse at dusk"}'
# HTTP/1.1 402 Payment Required
# PAYMENT-REQUIRED: <base64 of the JSON below>
# {"x402Version":2,"accepts":[{"scheme":"exact","network":"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
#   "asset":"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU","amount":"4250","payTo":"6Bt7cFqEYPZhMS661vAGkjcGpFGW85BCH9XicLYusBLf",
#   "maxTimeoutSeconds":60,"extra":{"feePayer":"...","memo":"xm_...","paymentFlow":"upfront"}}]}

# 2. sign that USDC transfer with your agent's Solana wallet, retry the SAME body
curl https://zinf.dev/v1/images/generations \
  -H "PAYMENT-SIGNATURE: <base64 signed payment>" \
  -H "Content-Type: application/json" \
  -d '{"model":"pruna/p-image","prompt":"a lighthouse at dusk"}'
# HTTP/1.1 200 OK
# PAYMENT-RESPONSE: <base64 receipt: success, transaction, payer>
optional: a split (here 20% of the discount to buybacks)
curl -i https://zinf.dev/v1/images/generations \
  -H "X-Split: xinf=2000,custom=0,discount=8000" \
  -H "Content-Type: application/json" \
  -d '{"model":"pruna/p-image","prompt":"a lighthouse at dusk"}'
typescript (@x402/fetch + @x402/svm)
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactSvmScheme } from "@x402/svm/exact/client";
import { createKeyPairSignerFromBytes } from "@solana/kit";

const signer = await createKeyPairSignerFromBytes(walletSecretBytes);
const client = new x402Client().register("solana:*", new ExactSvmScheme(signer));
const pay = wrapFetchWithPayment(fetch, client);

const res = await pay("https://zinf.dev/v1/images/generations", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ model: "pruna/p-image", prompt: "a lighthouse at dusk" }),
});
console.log(await res.json()); // { data: [{ url }] }

over MCP

An unpaid media tool call returns an error whose structured content is the payment requirements. Retry the same call with the signed payment in _meta["x402/payment"]; the result carries the receipt in _meta["x402/payment-response"].