ContextFile
— credits
Docs · versioned with the code · HTML, markdown and llms.txt

Built for agents to read first.

Payments

There are three ways to pay. All land in the same ledger: the payment becomes an escrow hold, the signed verification report decides, and the hold either pays the seller or goes back to whoever paid.

RailAccountWho funds itLands in the ledger as
CreditsYesA person, by card through StripeA hold from the principal's credits, under the agent's mandate
x402NoThe agent's own USDC walletA hold keyed to the payer wallet
MPP sessionNoOne deposit through a Stripe or Tempo MPP clientOne session hold, drawn down by signed vouchers, settled once at close

Each offer document (/offers/{id}) lists the rails that can buy it in its payment block, so an agent can choose before it asks. Credits are always on; x402 and MPP show only when the operator has switched them on, and never for subscriptions.

Credits

One credit is 1.00 US dollar. A person buys credits by card (Pricing), connects an agent, and the agent buys under its mandate with purchase_artifact or POST /v1/orders and a Bearer token. Subscriptions are paid from credits only.

x402: buy without an account, in USDC

x402 is an open payment protocol over HTTP status 402. An agent with a USDC wallet asks to buy, gets a quote, signs a transfer authorization, and retries. ContextFile verifies and settles the transfer through an x402 facilitator and holds the money in escrow like any other order.

x402 is off until the operator switches it on, and runs on a test network until legal review of stablecoin payments is done. A listing page says whether it is on.

1. Ask to buy, get a 402 quote

Send the purchase with no Authorization header:

POST https://mcp.contextfile.ai/v1/orders
Content-Type: application/json

{ "listing_id": "<listing id>", "formats": ["md"] }

The answer is 402 Payment Required with the x402 payment requirements:

{
  "x402Version": 1,
  "error": "payment_required",
  "accepts": [{
    "scheme": "exact",
    "network": "base-sepolia",
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "maxAmountRequired": "4000000",
    "payTo": "0x...",
    "resource": "https://mcp.contextfile.ai/v1/orders",
    "maxTimeoutSeconds": 300,
    "extra": {
      "name": "USDC",
      "version": "2",
      "quote_id": "q1....",
      "quote_expires_at": "2026-11-01T14:07:11.000Z",
      "listing_id": "<listing id>",
      "formats": ["md"],
      "price_cents": 400,
      "escrow": "hold_and_settle",
      "floor": 0.9
    }
  }]
}

maxAmountRequired is the live price of the basket in USDC base units (6 decimals, so 4000000 is 4 USDC). The figures here are Example values. The price always comes from the live listing, never a fixed number. The quote expires after maxTimeoutSeconds (Example: 5 minutes).

2. Pay with an X-PAYMENT header

Sign an EIP-3009 transfer authorization for exactly maxAmountRequired to payTo, and send the same request with the base64 payment payload in X-PAYMENT. Send the quote_id back in the body (or in an X-ContextFile-Quote header) so the quote's expiry and price hold:

POST https://mcp.contextfile.ai/v1/orders
Content-Type: application/json
X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLC4uLn0=

{ "listing_id": "<listing id>", "formats": ["md"], "quote_id": "q1...." }

A client that does not send the quote id pays the live price at that moment; its authorization's validBefore bounds the wait.

The payment is refused, and nothing is settled, when:

  • the quote has expired (quote_expired, with a fresh quote in accepts),
  • the authorization is for more than the maximum (amount_above_max) or less than the price (amount_below_price),
  • the price changed since the quote (price_changed),
  • the facilitator does not verify the signature or the wallet's funds (payment_invalid).

Every refusal is a 402 with new requirements, so the agent can pay again.

3. The payment lands as a hold

HTTP/1.1 201 Created
X-PAYMENT-RESPONSE: eyJzdWNjZXNzIjp0cnVlLCJ0cmFuc2FjdGlvbiI6IjB4Li4uIn0=

{
  "order_id": "<order id>",
  "state": "held",
  "escrow_cents": 400,
  "payment": { "rail": "x402", "payer": "0x...", "network": "base-sepolia", "tx": "0x..." },
  "order_token": "x4o....",
  "status_url": "https://mcp.contextfile.ai/v1/x402/orders/<order id>",
  "download_url": "https://mcp.contextfile.ai/v1/x402/orders/<order id>/download",
  "settles_on": "report_floor_check"
}

Keep order_token. It is the wallet's proof of the order: the paid request carried an authorization only the wallet could sign, and the token is bound to that order and that payer. Send it as X-ContextFile-Order-Token to read the order or download it. Another wallet's token does not open this order.

4. Release or refund

The signed report decides, exactly as for credits:

  • The report meets the floor: the hold settles. The seller accrues (T - c) / 2 and ContextFile keeps the rest, the same formula as every order. The escrow.release receipt carries payment: { rail: "x402", network, tx }, the transfer that funded it, and is anchored in the daily receipt tree like every receipt.
  • The report misses the floor: ContextFile sends the whole amount back to the paying wallet, and the hold returns to zero. A refund that fails on chain is retried; if retries run out it is recorded for manual action and still shows as owed.
GET https://mcp.contextfile.ai/v1/x402/orders/<order id>
X-ContextFile-Order-Token: x4o....

answers the state, the payment, any refund (pending, sent with its transaction, or failed), and the signed receipt once the escrow released.

GET https://mcp.contextfile.ai/v1/x402/orders/<order id>/download
X-ContextFile-Order-Token: x4o....

answers the artifact the same way download_artifact does, with artifact_digest and report_digest. A refunded order no longer downloads.

Pay per call with x402

A listing with a per-call price answers one question per call from its verified edition. Send the question to POST /v1/listings/{listing_id}/calls with no Authorization header and you get a 402 whose quote has extra.quote_kind set to per_call and the per-call price as the maximum. Retry with X-PAYMENT and the quote_id. An answered call settles the transfer, then holds and releases it through the same escrow as a purchase; the response carries the cited answer, charged_cents, order_id and the transfer. A question the edition does not cover answers no_answer and the authorization is never submitted, so nothing is charged. A per-call order never downloads the artifact. With a Bearer token the same path pays from credits, capped by the agent's mandate (MCP: commerce_buy with action: "call").

What x402 does not cover

  • Subscriptions: a wallet cannot be billed each cycle without a mandate, so living artifacts are paid from credits.
  • Sellers are paid out as today. USDC comes in; seller payouts do not change.
  • Agents that also hold a ContextFile account pay with credits when they send a Bearer token. A request with a token is always the credit purchase.

MPP sessions

Deposit once, pay for many calls, settle once.

MPP (the Machine Payments Protocol from Stripe and Tempo) suits an agent that will make many paid calls in a row. It deposits once, then pays for each call with a signed voucher instead of a new payment. ContextFile holds the deposit as one session hold, turns each voucher into an ordinary escrowed order, and settles the whole session in one transfer when it closes.

MPP is off until the operator switches it on, and runs on a test network until legal review is done. A listing page and the offer document say whether it is on.

1. Open a session on a deposit

Make the deposit with your MPP client, then open a session with its reference and the Ed25519 public key that will sign your vouchers (raw 32 bytes, base64url):

POST https://mcp.contextfile.ai/v1/mpp/sessions
Content-Type: application/json

{ "deposit_ref": "0x...", "voucher_key": "<base64url Ed25519 public key>" }

ContextFile asks the MPP rail to confirm the deposit, who made it and how much landed, and answers:

{
  "session_id": "<session id>",
  "session_token": "mps....",
  "state": "open",
  "deposit_cents": 2000,
  "cumulative_cents": 0,
  "expires_at": "2026-11-02T12:00:00.000Z",
  "calls_url": "https://mcp.contextfile.ai/v1/mpp/sessions/<session id>/calls",
  "close_url": "https://mcp.contextfile.ai/v1/mpp/sessions/<session id>/close"
}

One deposit opens one session; sending the same open again returns the same session. The figures are Example values, as are the deposit limits (Example: 1 to 500 credits' worth) and the session lifetime (Example: 24 hours).

2. Pay for each call with a voucher

A voucher states the running total you authorize for the session, in cents, and the listing this call buys. Sign the exact string

cf-mpp-voucher-v1|<session id>|<cumulative_cents>|<listing id>

with your voucher key, and send it with the session token:

POST https://mcp.contextfile.ai/v1/mpp/sessions/<session id>/calls
Content-Type: application/json
X-ContextFile-Session-Token: mps....

{ "listing_id": "<listing id>", "formats": ["md"],
  "voucher": { "cumulative_cents": 400, "signature": "<base64url>" } }

The total must rise by exactly the price of this call (the offer document has it). The call answers 201 with the order, the draw, the new total and what is left of the deposit. The order is held in escrow and settles on the signed report like any other.

A voucher is refused, and nothing is drawn, when its total does not rise over the last accepted one (voucher_not_increasing, which is what a replayed voucher gets), when it rises by a different amount than the price (voucher_amount_mismatch), when it goes past the deposit (voucher_over_deposit), or when the signature does not verify under the session's key (voucher_invalid). The specific reason is in mpp_code.

3. Close and settle once

POST https://mcp.contextfile.ai/v1/mpp/sessions/<session id>/close
X-ContextFile-Session-Token: mps....

Closing stops new vouchers. While any call's order still waits for its report, the answer is 202 with outcome: "waiting" and the session settles on its own as soon as the last order settles. Then one settlement runs on the rail:

  • calls whose report met the floor are claimed from the deposit. The seller accrues (T - c) / 2 for each, the same formula as every order;
  • calls whose report missed the floor, failed-format surcharges, and the part of the deposit you never drew go back to you in the same transfer.

GET /v1/mpp/sessions/<session id> shows every draw, its order's state and, once settled, the settlement transaction with what was claimed and what was returned. A session that reaches its expiry closes the same way. Closing twice changes nothing.

Download what a call bought with GET /v1/mpp/sessions/<session id>/orders/<order id>/download and the session token.

Catalog channels

The same offer documents feed two catalog formats, rendered on request so a price change shows in the next response:

  • /.well-known/ucp is a UCP (Universal Commerce Protocol) business profile. It names ContextFile's REST and MCP services, lists the live offers under the ai.contextfile.offers capability, and lists the payment handlers that are on.
  • /feeds/acp.json is an ACP (Agentic Commerce Protocol) product feed, one product per one-off offer at its live price in cents. It is for discovery: OpenAI approves in-app checkout only for physical goods today, so buying happens on the rails above.

Both are checked in CI against the published UCP and ACP schemas.

Receipts and checks

Receipts verify offline against /.well-known/receipt-keys.json, and /receipts/{id}/proof shows a receipt's place in its day's anchored tree. The full API is in the API reference.

Version 2, updated 2026-11-01.

This page as markdown · llms.txt

Payment methods

CreditsOn. Card through Stripe, then agents buy under a mandate. Subscriptions are credits only.
x402Not switched on yet.
MPP sessionsNot switched on yet.

Every method lands as a hold in the same escrow and settles on the signed report. How each one works. Agents can also discover offers through the UCP profile and the ACP feed.