Pay per call
The keyless, pay-per-call way for agents to use CueFrame — over MCP (recommended) or REST. No account, no API key.
The usual way in — MCP, CLI, REST — assumes a human signed in once and minted a key. Pay-per-call doesn't. An agent pays per request with a wallet signature: no signup, no key, no account to provision. The payment is the request.
It's built on x402 — the HTTP 402 Payment Required
standard. For agents, the best way in is MCP: you get CueFrame's typed tools
plus discovery plus per-call payment in one session, and your MCP client handles
the pay-and-retry for you. There's also a plain REST path if you
prefer raw HTTP. Same wallet, same USDC-on-Base payment either way.
Recommended: over MCP
Point an x402-aware MCP client at the open transport:
https://api.cueframe.ai/v1/mcp/x402Connecting and listing tools is free — no bearer, no signup. When you call a paid
tool, it returns a payment-required result carrying the price quote
(accepts[]); your client signs the payment, puts it in the tool call's
_meta["x402/payment"], and retries. Libraries like @x402/mcp's client wrap
all of that, so you just call the tool:
import { wrapMCPClientWithPaymentFromConfig } from "@x402/mcp";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
// Your agent's wallet — the only credential it needs. Fund it with USDC on Base.
const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY);
// Wrap an MCP client pointed at /v1/mcp/x402; paid tools sign + retry automatically.
const paid = wrapMCPClientWithPaymentFromConfig(mcpClient, {
schemes: [{ network: "eip155:*", client: new ExactEvmScheme(account) }],
});
// No key, no signup — the wallet pays per tool call.
await paid.callTool("compose", { projectId });Why MCP is the recommended path: the tools are typed and self-describing, so
an agent discovers what to call from tools/list instead of hand-building HTTP
requests; discovery, payment, and the call all live in one session; and the
client library turns a payment-required into a signed retry automatically. It's
the most agent-native way to drive CueFrame.
(The key-authenticated MCP endpoint /v1/mcp — browser login or a cf_* key —
is unchanged; reach for /v1/mcp/x402 when you want keyless pay-per-call.)
What you pay
Per call, in USDC — the same prices whichever path you use. Reads (list, get,
poll a job) are $0.01.
| Call | Endpoint / tool | Price |
|---|---|---|
| Import footage | import_media · POST /v1/media | $0.01 |
| Detect faces + transcript | POST /v1/media/:id/detect-subjects (REST) | $0.10 |
| Suggest clips | suggest_briefs · POST /v1/media/:id/suggestions | $0.50 |
| Compose a video (Director) | compose · POST /v1/projects/:id/compose | $1.50 |
| Render to MP4 | create_render · POST /v1/projects/:id/renders | $0.50 |
| Reads (list / get / poll) | list_media, … · GET /v1/… | $0.01 |
The live price rides on every payment-required, so a client never hardcodes it —
read accepts[].amount and pay what's quoted.
You pay for delivered work
Async calls — compose, render, import — are charged on delivery, not on enqueue. If the job fails, you aren't charged: the payment releases and nothing settles on-chain. You only pay when the asset is actually produced.
Also on REST
Prefer raw HTTP? The same payment works directly on the REST API — hit a priced
endpoint, get a 402, sign, and retry with a PAYMENT-SIGNATURE header:
your agent ──▶ POST /v1/projects/:id/renders
◀── 402 { accepts: [ { asset: USDC, amount, payTo } ] }
your agent ──▶ POST … + PAYMENT-SIGNATURE (signed USDC transfer)
◀── 200 { render job }import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY);
const pay = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: "eip155:*", client: new ExactEvmScheme(account) }],
});
const res = await pay("https://api.cueframe.ai/v1/projects/PROJECT_ID/renders", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ /* … */ }),
});Same wallet, same prices as the table above — only the carrier differs (an HTTP
header instead of a JSON-RPC _meta field). Everything else is the plain REST
API reference.
Long-running calls
Compose and render return a job. Poll it or register a webhook — exactly like every other surface. See the Quickstart for the ingest → compose → render loop, which works identically whether you authenticate with a key or pay per call.