the402
Dashboard
200 OK: provider guide

Provider Guide

List the endpoint you already run, get found by agents that read a free verdict before they buy, and take your money out of a contract the402 cannot touch.

Overview

the402 sells your service to agents. You run an x402 endpoint; the402 finds you buyers, checks your endpoint and vouches for it with a verdict, routes each payment to your own payment contract, and hands you every paid order with a signed header. Agents can do everything on this page over the API. People can do the same from the dashboard.

the402 is the purchasing platform for AI agents: a marketplace of machine-readable x402 services, a trust assessment (a verdict) for each service and provider, x402 payment from the agent’s own wallet, a record of every purchase decision, and owner-set purchasing rules, which are being prepared as a local guard and planned as organization controls. Agents find x402 endpoints here, read a free verdict about whoever runs them, and buy. You keep your own endpoint, your own pricing and your own payment relationships. the402 is not the only door, and the 5% applies only to a purchase that starts and finishes through the402’s own checkout.

Three rungs

1
Indexed

the402’s Bazaar walk has seen your endpoint and holds a record of it. Nothing is required of you, and nothing is charged. Live The walk runs, and every indexed endpoint has a public page in the explorer.

2
Claimed

You have proved you operate it: a .well-known token, a DNS TXT record, a signature from the payTo key, a proof-linked wallet, or a signed liveness check on your own webhook. Claiming unlocks the sandbox, funded probes and the trust settings on your subject. Live Claims are open. A provider who receives work through webhooks verifies the endpoint in one click from the dashboard checklist; the402’s own signed liveness probe is the proof.

3
Listed

The endpoint sells through the402’s checkout. Listing starts from a claim, and only a Listed endpoint is sold through. Paused Instant checkout is switched on and the platform is paused, so a Listed endpoint goes on sale the day it reopens.

A public x402 endpoint is optional. With one, the402’s free hourly checks and paid verification add to your sales record and endpoint mode lets the402 deliver through your own URL; without one, your verdict is built from the sandbox and your checkout outcomes.

Where the platform stands today. the402 paused new paid activity on 2026-08-02, so every paid route answers 503 with status: "paused". The non-custodial checkout is switched on: the catalog charges list prices with no markup, the checkout names each provider’s payment contract, and deferred features answer 410. The first purchase completes the day the platform reopens.

Instant services only. What the402’s checkout sells is a fixed-price service that answers in one call. Negotiated pricing, asynchronous work and work delivered by people are deferred, not retired: the code stays, a later lane re-bases it, and the reads keep working. See what is coming back.

Quickstart

Six steps from nothing to a listing that sells. Steps 1–3 are one-time.

1
Register as a provider

Pay $0.01 over x402 to POST /v1/register or POST /v1/provider/onboard, or sign up at the402.ai/dashboard. Save the api_key the response hands back. Details.

2
Accept the Provider Agreement

One click in Settings, or accept_terms_version on a listing write. It carries the one-price and no-steering undertakings, which is what makes the fee work. Details.

3
Point the402 at your endpoint

Name an endpoint_url on the listing and let the402 call the x402 endpoint you already run. Listings created before 2026-09-17 may instead take a signed dispatch at the webhook URL in Settings. Details.

4
List an instant service

POST /v1/services, or the dashboard. Instant, data_api, one fixed price the402 can charge exactly. Details.

5
Verify the signature, answer promptly

Check X-Platform-Secret, the timestamp and the HMAC, then post your result to the dispatch’s own callback_url. Answer inside the402’s inline window, 20 seconds under the checkout, and your deliverable lands in the buyer’s purchase response; miss it and they get an id to poll instead. The template’s own handler timeout is 15 seconds, which sits inside that budget. Details.

6
Get paid from your own contract

The buyer’s USDC lands in an ownerless splitter of yours; distribute() forwards 95% to your payout wallet. the402 never holds it. Details.

The provider starter template is in the repository under templates/provider/: a Cloudflare Worker with signature verification, a handler registry, both fulfilment modes worked through, and a sandbox solver. It is the shortest path to a receiver that is correct the first time. the402’s repository is not public today, so that path is open to people who already have access; everything the template does is specified on this page, and a receiver written from it alone is a correct one.

Already running an x402 endpoint?

Registering, accepting the Provider Agreement and claiming your endpoint are one command from the wallet that endpoint is already paid to. One command does the whole path for an x402 service: PROVIDER_PRIVATE_KEY=0x… node scripts/join-provider.mjs --endpoint https://… --price '$0.05' --name … --description …; add --endpoint-method POST when your endpoint charges on POST, and --identity-only when the URL is not an x402 endpoint. Paused

PROVIDER_PRIVATE_KEY=0x… node scripts/join-provider.mjs \
  --endpoint https://api.acme-widgets.com/x402/domain-check \
  --price '$0.05' \
  --name "Domain checks" \
  --description "WHOIS and certificate facts for a domain"

That wallet pays the $0.01 registration, signs the claim that proves you operate the endpoint, and is the address your splitter pays into. The key is read from the environment and never from a flag. --dry-run prints the four requests and sends none of them. The label above is on the join, not the script: paid activity is paused, so the registration payment in its first step cannot settle yet, and a run stops before it spends anything and says so.

the402’s repository is not public today, so the script is open to people who already have access. It is four ordinary API calls in the order this page documents, and doing them by hand gets the same result.

Sell over the API

A listing on the402 is your own x402 endpoint plus a record on the402 that agents can find, trust and buy. An agent does the whole of it over the API, in five calls, with no dashboard anywhere in the path.

1
Onboard, and get your key

POST /v1/provider/onboard (x402, $0.01) with name, description, accept_terms_version: "2026-09-15" and your first services[]. The answer carries your API key. Or POST /v1/register first and list later. Details. Paused

2
Your payment contract is created for you

No call to make. Once the Agreement is accepted and a payout wallet is on record, the402 creates your splitter on Base: 95% of every sale forwards to your payout wallet, 5% to the402. the402 never holds the money. Details.

3
Claim the endpoint

POST https://trust.the402.ai/v1/trust/claims with your X-API-Key: method: "signature", url (your endpoint), pay_to (its payout address), issued_at in unix seconds, the current claimant terms_version, and an EIP-712 ClaimSubject signature from the key behind that address. One call, verified in place; the answer names your subject_id. The typed data and the current claimant terms version are both published in the trust worker’s methodology document under claims. A claim may name the HTTP method the endpoint charges on, GET or POST; the402 checks the endpoint with that method. Send resource_method to name it; omitted means GET. Details. Live

4
List it

POST /v1/services with your X-API-Key: fulfillment_mode: "endpoint", endpoint_url, the trust_subject_id the claim just produced, an input_schema naming the fields a buyer must send, and a fixed price. The listing gate runs on the same call: it puts the listing on sale, or answers with what is missing. Details.

5
Answer the orders

Your endpoint verifies the X-The402-Order header on each paid order and answers. The answer is the deliverable. Details.

What your verification level lets you charge applies here as it does everywhere: up to $10 per purchase until your account is identity-verified, up to $500 after. Every listing created from 2026-09-17 delivers through an endpoint; webhook delivery is available only for listings created before that date.

Sell from the dashboard

A person does the same five things from the402.ai/dashboard, as a checklist on the provider Overview. Each step is performed on the page rather than described there, and the page reports where you stand rather than leaving you to read an error. Live

  • Review the Provider Agreement: one click, and it writes the same record an accept_terms_version on a listing write does
  • Confirm your payout wallet: the click that confirms is the click that creates your payment contract
  • Verify your service endpoint: the402’s own word for this is a claim, and a provider who receives work over a webhook verifies in one click
  • Review your listings: the three checkout fields, the price, and why a listing is waiting
  • Check your status: what the listing gate makes of your listings now

Nothing on that page is a different mechanism from the five calls above. Same routes, same records, a form instead of a body.

Registration

Two self-service doors, and no assisted path. Both create the account and hand back an api_key.

POST /v1/register $0.01

Register as a provider (or as both sides). name, description and type are required; webhook_url and capabilities are the rest of the useful ones. Idempotent: calling it again for a wallet that already registered returns the existing credentials. Paused

POST /v1/provider/onboard $0.01

The same thing, plus a services[] array and an optional accept_terms_version, so an agent lists in the same call it registers in. Paused

curl -X POST https://api.the402.ai/v1/provider/onboard \
  -d '{
    "name": "Acme Services",
    "description": "Domain and certificate checks for agents",
    "webhook_url": "https://api.acme-widgets.com/webhook/the402",
    "accept_terms_version": "2026-09-15",
    "services": []
  }'

Onboarding is never refused over the Provider Agreement. It creates the account, and without an acceptance your listings simply wait with blocked_reason: "terms_required" until you accept, which frees them in one click.

New registration is closed while the platform is paused. The two x402 doors answer 503 like every other paid route, and dashboard sign-up is blocked at the edge as well. An account that already exists keeps its login, its wallet, its listings and its data throughout. The pause stops new paid activity, not access. Paused

Your credentials

  • api_key: authenticates your API calls, and is what the402 sends back as X-Platform-Secret on every dispatch so you can tell a real one from a stranger’s
  • webhook_secret: the HMAC key. It signs job dispatches, connectivity probes, sandbox tasks and the endpoint-mode order header
  • Rotate the key with POST /v1/participants/rotate-key ($0.001 over x402: the payment signature proves the wallet). The old key dies immediately

The Provider Agreement

Current version 2026-09-15, published at the402.ai/provider-terms. It is where the one-price and no-steering undertakings live, and it is a fact the platform can point at rather than a page somebody may once have read: the402 relays a buyer’s payment authorization to your contract and posts a paid order to your endpoint, so what you agreed to has to be on the record.

Every door records the same thing

  • The dashboard: a button in Settings (POST /dashboard/api/settings/accept-terms). It is also the “retry my listings” button: it re-runs the gate on every press
  • A listing write: accept_terms_version on the body of POST /v1/services, PUT /v1/services/:id or either dashboard service write, so an agent accepts and lists in one request
  • Onboarding: accept_terms_version on POST /v1/provider/onboard, which is never refused over the Agreement but records one if you send it
  • PUT /v1/participants/:id: the API-only door, for a provider that registered over x402 and has no browser
  • An admin can also record an out-of-band acceptance for an account that already exists; it lands in the same table

Accepting a version you were not shown is refused, so a page loaded before a bump retries rather than minting an acceptance of terms nobody saw. The accept-terms button answers 409 stale_version naming the current one, and a stale accept_terms_version on a listing write or on PUT /v1/participants/:id answers 409 terms_required, whose terms.version is what to send back. Nothing is written either way. Accepting twice is a no-op. Acceptance is recorded whatever the checkout flag says. It is collected before the cutover, deliberately, so nobody’s catalogue goes quiet on flip day. Live

What you are agreeing to, in one line. The price a buyer sees on the402 is the price you charge anywhere, and you will not use a the402-originated delivery to send that buyer somewhere else to pay. Why that is the deal.

Listing Services

List through the API or the dashboard. Under the checkout a listing is accepted only as instant: fulfillment_type: "instant", service_type: "data_api", pricing_model: "fixed". Anything else is refused 400 with code: "deferred" on a write, and answers 410 deferred on a purchase. The listing is well formed, the402 just does not sell that shape yet.

A new listing also delivers through your own x402 endpoint: fulfillment_mode is endpoint when you name nothing, and naming webhook on a create is refused 400 with code: "webhook_mode_closed". Listings created before 2026-09-17 keep their webhook and can be moved to an endpoint at any time, and not back. See the checkout fields.

curl -X POST https://api.the402.ai/v1/services \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "name": "Domain Health Check",
    "description": "DNS, certificate and uptime check for any domain.",
    "price": { "fixed": "$0.02" },
    "fulfillment_type": "instant",
    "service_type": "data_api",
    "pricing_model": "fixed",
    "estimated_delivery": "instant",
    "category": "web",
    "tags": ["dns", "ssl", "health"],
    "accept_terms_version": "2026-09-15",
    "input_schema": {
      "type": "object",
      "required": ["domain"],
      "properties": { "domain": { "type": "string" } }
    }
  }'

input_schema is worth writing properly: the402 validates a buyer’s brief against its required fields before you are ever called, so a missing field is a 400 naming required_fields rather than a job you have to fail.

Sellable prices only

Your price string travels verbatim to the x402 middleware, where two parsers read it and can disagree by a factor of a thousand. So it has to be the canonical $ followed by digits and at most six decimals, between $0.0001 and $10,000. "$1,000.00" and "USD 5.00" are refused: 400 unsellable_price when you write one, 409 if one is already on a listing somebody tries to buy. No range and no minimum-only: that is a negotiation, and negotiation is deferred.

What your verification level lets you charge

A provider may charge up to $10 per purchase until they verify their identity, and up to $500 after. The limit applies to the list price and is checked when a listing is saved and again at every purchase. Both refusals are price_over_tier_cap: 400 when you save a listing, 409 before any 402 when somebody tries to buy one. A listing already on file that is over the limit is parked with blocked_reason: "price_over_tier_cap" until you lower the price or verify. Identity verification is under Settings in the dashboard.

Editing and taking a listing down

PUT /v1/services/:id judges the merged listing, so a patch that names no kind field leaves the kind alone. A deactivation (status: "inactive"), an edit to a listing that is already inactive, and a DELETE are never gated on the Provider Agreement or the listing kind: you must always be able to take a listing down or fix one that is waiting, whatever you have or have not accepted. The checkout fields are still validated on the merged listing, though. Under the checkout, a bare {"status": "inactive"} on an endpoint-mode listing whose stored endpoint_url no longer passes the URL validator answers 400 invalid_endpoint_url, so fix the URL in the same request.

The Checkout Fields

Three fields on a listing that the checkout reads, and every listing write path accepts them. Live

FieldMeaning
fulfillment_modeendpoint on every new listing: the402 calls the x402 URL you already run. webhook, where the402 dispatches a job to your receiver, is kept for listings created before 2026-09-17
endpoint_urlRequired in endpoint mode. https only, checked for SSRF when you write it and again when the402 sends to it
trust_subject_idThe claimed trust subject the listing sells under (sub_ + 16 hex). First-party endpoints are exempt

On a create, fulfillment_mode is endpoint: it is what you get when you name nothing, and naming webhook is refused 400 with code: "webhook_mode_closed". On an edit it keeps whatever is stored, because a description change must never silently re-point how a listing is fulfilled, and a listing created before 2026-09-17 keeps its webhook until you move it. A move goes one way: webhook to endpoint is accepted, and endpoint back to webhook is the same 400. pull is refused by name as deferred rather than as an unknown value.

Why a Listing Waits

Under the checkout a listing waits until every precondition is met, and one click frees it once the missing piece exists. Nothing is deleted and nothing is lost while it waits.

The row itself carries only a sentinel: status: "inactive" with status_reason: "Awaiting checkout setup", the same string whatever is missing, because it is what the platform looks for when it decides a row is parked rather than switched off by you. What is missing comes back on the answer, as listings_blocked and listings_blocked_reason:

listings_blocked_reasonWhat is missing
terms_requiredYou have not accepted the current Provider Agreement
splitter_pendingYour splitter contract is not confirmed on chain yet
fulfillment_mode_requiredNo fulfilment mode, or endpoint mode with no valid endpoint_url
webhook_secret_requiredThe listing is in endpoint mode and the account has no webhook secret; rotate one from Settings, or an accepted PUT /v1/participants/:id, which generates one when none exists.
claim_requiredThe listing names no claimed trust subject
deferredA kind the402 does not sell through its checkout
gate_unavailablethe402 could not read one of the above and refused to guess. Retry

You read that reason on the answer of the write that parked the listing, POST or PUT /v1/services, and on the other surfaces that re-run the gate and report where you stand: PUT /v1/services/:id with status: "active", POST /dashboard/api/settings/accept-terms, POST /dashboard/api/provider/settings/rotate-webhook-secret, and saving a payout wallet. PUT /v1/participants/:id and the admin splitter provision route re-run the gate too but do not echo the reason, so poll one of the others if you are driving this from an agent.

listings_blocked counts the rows the reported reason stopped; rows a later precondition would stop are not in it, so clear the reason shown and check again.

Receiving Work

Two ways a paid purchase reaches you. Every listing created from 2026-09-17 uses the first; the second is kept for the listings that already existed.

  • Endpoint mode: the402 sends one signed POST to the x402 URL you already run, and your answer is the deliverable. Minimal integration, not zero: you have to honour a verified order header instead of your own 402
  • Webhook mode: the402 POSTs a signed job dispatch to your registered webhook_url, and you post the result back to the thread. This is the mode every existing receiver already speaks, and it is available only for listings created before 2026-09-17; those keep working and can be moved to an endpoint at any time

In both modes the buyer has already paid before you are called. Under the checkout that payment went to your contract, not to the402, which is why the dispatch happens after settlement rather than before it.

The three events your receiver will see

typeWhat to do
job_dispatchDo the work. Post the result to the dispatch’s own callback_url
connectivity_probeAcknowledge 200 and create no job. This is the free hourly liveness sweep
sandbox_taskSolve it and POST the answer to the task’s callback_url. Unpaid, opt-in, and only for a claimed endpoint
// type: "job_dispatch"
{
  "type": "job_dispatch",
  "job_id": "job_def456",
  "thread_id": "thread_abc123",
  "service_id": "svc_xyz",
  "brief": { "domain": "example.com" },
  "deadline": "2026-09-14T12:00:00.000Z",
  "callback_url": "https://api.the402.ai/v1/threads/thread_abc123/update"
}

// …plus these two, under the checkout
{ "order_id": "ord_…",
  "payment": { "tx_hash": "0x…", "amount_usd": 0.02, "pay_to": "0x…" } }

Post to the dispatch’s own callback_url. Do not compose /v1/jobs/:id/update from the job id: that route writes a deliverable straight onto the job, goes round the one place a delivery is recorded, and answers 410 deferred under the checkout. The callback_url in the payload is the one door, and it is already the thread’s.

The liveness sweep runs while paid activity is paused. The free hourly signed probe is what proves your receiver can take a dispatch: two consecutive failures are enough for the pre-purchase gate to stop selling your services, the third deactivates the listings, and a recovery brings them back (under the checkout, through the listing gate rather than straight back on sale). It is free, so it does not stop when the platform does. It did stop with the kill switch from 2026-08-02 to 2026-09-14, which means the first probes after that gap may deactivate listings whose receivers went down during it. If yours is one, fix the receiver and run the self-test: a pass clears the block without waiting for the next hour.

Endpoint Mode

Every listing created from 2026-09-17 delivers this way. Set fulfillment_mode: "endpoint" and an endpoint_url on the listing, and the402 delivers through the URL you already run.

Instead of taking a dispatch, let the402 call the endpoint you already run. It sends one signed POST to your endpoint_url with the buyer’s brief as the body, and your answer is the deliverable. Paused

HeaderContent
X-The402-Orderbase64url of the order’s canonical JSON: the ids, the buyer, the amount, your splitter, the settlement transaction and a callback_url
X-The402-Signaturesha256= followed by the hex HMAC-SHA256 over ${timestamp}.${orderB64}.${rawBody}, keyed with your webhook_secret: the same sha256=<hex> shape as the webhook pair
X-The402-TimestampUnix seconds, same 5-minute replay window
X-Platform-SecretYour API key

The header and the body are signed together, so a proxy cannot pair one buyer’s paid order with another buyer’s brief, and under different header names from the webhook pair, so a receiver never verifies a signature over one content under the name of another.

Honour a verified order instead of your own 402. Answering 402 to one is recorded as order_header_not_honoured: the402 has already taken the buyer’s money and the buyer has nothing. the402Order() and the402OrPay() in the provider template are the reference middlewares. The first refuses a forged header 401, the second wraps your own paywall and skips it for a verified order.

How your answer is read

You answerRecorded as
2xx with a JSON objectDelivered. That object is the deliverable
2xx, empty or not JSONAccepted: the402 waits for your callback instead
402dispatch_failed: the order header was not honoured
3xx, 404, 408, 410, 429, 5xx, timeout, network errordispatch_failed: the402 could not reach a working endpoint
Any other 4xx (400, 401, 403, 422…), or a body over 1 MiBprovider_failed: you answered, and refused

The four reachability codes sit with the 5xx deliberately: a stale endpoint_url answering 404, a receiver timing out on its own side, a 410, or a 429 refusing the request outright are none of them you judging the work, and grading them as refusals would publish a moved URL as a run of quality failures. The distinction is not cosmetic: one of those says the402 could not deliver the call, and the other says you would not. They weigh differently in your verdict, and neither one carries your body, your host or your error text anywhere. A failure travels as a code.

Webhook delivery (existing listings)

Webhook delivery is available only for listings created before 2026-09-17; those keep working and can be moved to an endpoint at any time. Nothing below has changed for them, and a move is one PUT /v1/services/:id naming fulfillment_mode: "endpoint" and an endpoint_url.

Every dispatch carries three things, and you must check all three. The signature covers the timestamp and the body together. Signing the body alone would let a captured dispatch be replayed forever.

HeaderContent
X-Platform-SecretYour API key: proves the caller is the402
X-Webhook-TimestampUnix seconds. Reject anything more than 5 minutes old
X-Webhook-Signaturesha256= + hex HMAC-SHA256 over ${timestamp}.${rawBody}, keyed with your webhook_secret
// Node / Workers: reject before you parse anything
const secret = request.headers.get("x-platform-secret");
if (secret !== THE402_API_KEY) return new Response("Unauthorized", { status: 401 });

const ts = request.headers.get("x-webhook-timestamp");
if (Math.abs(Math.floor(Date.now() / 1000) - Number(ts)) > 300) {
  return new Response("Stale", { status: 401 });
}

const body = await request.text();
const expected = "sha256=" + crypto
  .createHmac("sha256", WEBHOOK_SECRET)
  .update(`${ts}.${body}`)
  .digest("hex");

if (request.headers.get("x-webhook-signature") !== expected) {
  return new Response("Unauthorized", { status: 401 });
}
# Python: the same three checks
import hmac, hashlib, time

if request.headers["X-Platform-Secret"] != THE402_API_KEY:
  return Response(status=401)

ts = request.headers["X-Webhook-Timestamp"]
if abs(int(time.time()) - int(ts)) > 300:
  return Response(status=401)

expected = "sha256=" + hmac.new(
  WEBHOOK_SECRET.encode(), f"{ts}.{raw_body}".encode(), hashlib.sha256
).hexdigest()

if not hmac.compare_digest(request.headers["X-Webhook-Signature"], expected):
  return Response(status=401)

Answer promptly

Return 200 OK as soon as you have verified the request. { "received": true } is enough. For an instant service, answering inside the402’s inline window is what puts your deliverable in the buyer’s purchase response: 20 seconds under the checkout, which is switched on. Longer than that and the buyer gets an order id to poll instead, which still works and reads worse. The provider template’s own handler timeout is 15 seconds, which is sized for that budget and sits inside it.

Compare in constant time, and treat a rejected secret as a configuration problem rather than a transport one: a receiver that 401s a real dispatch is recorded as unreachable, and two of those are already enough to stop your services selling.

Delivering

created dispatched completed verified
  • created: the purchase settled and the job exists. No settlement, no job, ever
  • dispatched: the402 has called your receiver, or your endpoint
  • completed: you posted the deliverable
  • verified: instant work auto-verifies the moment you report completion. The buyer may also verify explicitly, which is the strongest evidence the402 gets about you
// Post to the callback_url the dispatch handed you
await fetch(dispatch.callback_url, {
  method: "POST",
  headers: { "X-API-Key": THE402_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    status: "completed",
    deliverables: { dns: "ok", certificate_expires: "2027-02-01" }
  })
});

Send status: "failed" with a reason when you cannot do the work. That is a worse outcome than a delivery and a much better one than a timeout: a refusal you state is one fact on your record, and silence is an outage.

Verify and dispute are events under the checkout. The buyer prepaid into your contract, so a verify releases nothing and a dispute claws nothing back. Both are recorded, and a dispute is read by a person before any verdict moves. Legacy: before the cutover, payment routed through the legacy holding contract the402 is winding down, a verify triggered the release, and an expiry or a failure returned the buyer’s money automatically.

Getting Paid

Every provider gets a keyless, ownerless splitter contract of their own on Base. The buyer’s USDC lands there, and distribute(), which anyone may call, forwards 95% to your payout wallet and 5% to the402. Your payment contract is created only after you accept the Provider Agreement, and its creation is recorded permanently on Base. Paused

1
The buyer signs

One gasless USDC authorization, straight to your contract’s address.

2
the402 calls you

Only after the payment settled. You deliver.

3
distribute() forwards it

95% to your payout wallet, 5% to the402. A five-minute job calls it; so may you.

the402 never holds your money, cannot freeze it and cannot spend it: the contract has no owner, no setters and no withdraw. Nobody, the402 included, can take the provider’s share out of it. The one thing that follows from that is worth saying plainly: if a delivery goes wrong, the402 can stop selling your endpoint and publish what it observed, but it cannot return a buyer’s money, because it never had it.

The five-minute forwarding job keeps running while the platform is paused, because that money is already yours. distribute() is permissionless, so you never depend on the402 to call it.

Legacy: before the cutover, payment routed through the legacy holding contract the402 is winding down, released on verification into a the402-held provider balance, and a settlement job paid that out every six hours. held_usd and pending_usd below are that flow, and the contract is being retired.

One Price Everywhere

Under the checkout the provider absorbs the fee at one price everywhere.

Under the checkoutLegacy: before the cutover
You list at$50.00$50.00
The buyer pays$50.00$52.50 (agent_price)
You receive$47.50, through your splitter$49.875, from the holding contract
the402 receives$2.50$2.625

That is what the Provider Agreement’s one-price and no-steering clauses are for: the price a buyer sees on the402 is the price you charge anywhere, so nobody has an economic reason to route around the402, which is the whole basis for the402 not trying to be the only door. Legacy: before the cutover the catalog rendered the marked-up figure above, the fee was a markup on the buyer rather than a share of your price, and the holding contract then took its 5% of the marked-up total, which is why a $50.00 listing paid $49.875 rather than the $50.00 asked for.

What the 5% buys

Discovery, trust intelligence, traceability and an easier purchase, and it applies only to a transaction that both starts and finishes through the402’s checkout. Your own endpoint, your own customers and your own pricing relationships are none of the402’s business and pay it nothing.

No steering, and how the402 checks

A deliverable the402 relays is scanned for a payment address or an off-platform payment link sitting next to language about paying elsewhere. A high-scoring one becomes a record and a signal, a person reads it before anything happens to your listing, and the scanner can neither block a delivery nor take a listing down by itself. The deliverable is never stored, never logged and never transmitted. The record holds the address or host found, the phrase keys near it, and a hash of the content, which is enough to tie a scan to a delivery and not enough to reconstruct one. Every scan is written down, including the ones that find nothing: “scanned, nothing found” is the answer you are owed when you ask what the402 does with your deliverables. Paused

Tracking Earnings

GET /v1/provider/earnings free

Your breakdown, plus recent settlement transactions. Free, and it keeps answering while everything paid is paused.

{ "earnings": {
  "settled_usd": 0, // paid out to you
  "held_usd": 0, // legacy: held against a pre-cutover job
  "pending_usd": 0, // legacy: released, awaiting the payout job
  "awaiting_distribution_usd": 0 // in YOUR splitter, not yet forwarded
} }

awaiting_distribution_usd appears under the checkout only, and it is the402’s bookkeeping rather than a reading of the contract: your share of purchases that settled into your splitter and have not been forwarded yet. It is USDC in your contract: not a the402-held balance, and not something the402 could withhold.

The dashboard shows the same figures at the402.ai/dashboard, along with a gasless USDC send from an embedded wallet and a USD cash-out through Coinbase Offramp. Live

Take your data with you. GET /dashboard/api/export (the Settings button calls it) hands you one JSON document with everything the402 holds about you: your listings including the ones waiting, your threads and messages, your orders as buyer and as provider, your splitters, the deliverable scans, your terms acceptances. It names what it withholds and why, it reads no feature flag, and it answers identically whatever else is switched off. Live

Claiming Your Endpoint

A claim is how you prove the endpoint the402 has indexed is yours. It is what turns an indexed record into an account you control, and it is the precondition for listing, for the sandbox, and for any probe the402 runs against you. Live The claim routes are on. From the dashboard checklist a webhook provider verifies in one click; the other methods are described below.

MethodWhat you do
well_knownServe a token the402 issues at /.well-known/the402.json on the endpoint’s own origin. The document is either {"claims": ["<token>"]} or {"the402_claim": "<token>"}; the token is the the402-claim-<32 hex> string the claim answer gave you.
dns_txtPublish a TXT record at _the402.<host> whose value is the402-claim=<token>. The prefix is part of the record, and a bare token is not read
webhookNothing to publish: the402’s free hourly sweep already signs its connectivity probe with your own webhook secret, so a passing check from the last 24 hours proves the origin of your registered webhook in one call, always as an identity claim whose pay_to must be a wallet already on your account (no record, or a failing or stale one, answers 422 webhook_not_live: run the dashboard webhook self-test and claim again)
signatureSign a typed claim with the key behind the endpoint’s payTo address
wallet_claimClaim through a wallet you have already proved with a signature

A claim may name the HTTP method the endpoint charges on, GET or POST; the402 checks the endpoint with that method. Send resource_method with the claim; omitted means GET, which is what most x402 endpoints charge on.

If your service has no public x402 endpoint, claim with identity_only: true: the402 verifies the origin or the wallet and never probes the URL. An identity claim names no resource, so resource_method is ignored there.

Dashboard providers claim from the Services page; API providers use the trust worker's claim routes or the join script.

The three origin methods are the strong ones: only they corroborate a pair nobody else has named, because only they prove control of the host as well as the address. One verified claim per endpoint; a second claimant is refused rather than queued. Releasing a claim gives the endpoint back to the indexed rung and never deletes the402’s record of it.

Claiming also gets you the settings on your own subject: an opt-in for paid probes, a display name and description the402 will show instead of what it inferred, and the record of which terms you accepted.

Your Verdict

the402 publishes a verdict about each endpoint, not a score. There are four, and the default is a silence:

  • verified: production evidence from several independent observers, and nothing unresolved against it
  • degraded: answering, and not clearing the bar for verified
  • failed: the402 has seen it fail, or the payTo does not match what it advertises. This one blocks purchases through the402
  • unknown: the402 has no statement. It is the default, it never blocks anything, and it is not a bad grade

Verdicts are free to read (GET /v1/reputation/:wallet, no key, no wallet) and the only number that comes out of one is its band: 100, 50, 0, or none at all for unknown. The ruleset is published in full at how the402 decides, and every statement names the methodology it was made under (the402-trust-v1).

Where the evidence comes from

  • Free availability sweeps: does the endpoint still answer a valid 402
  • Funded probes, which run only against an endpoint whose operator claimed it, accepted the terms and opted in. the402 pays for no probes: one is funded by you, by a buyer verifying you, or by a pool the402 tops up for disputes
  • Signed buyer attestations, on-chain activity, the sandbox, and the402’s own checkout outcomes

The parts that protect you

  • A verdict can be contested. As the claimant you can file a dispute against the verdict, an observation or a flag; it goes on a public register with your reason, and a person reviews it. The reviewer’s note stays private
  • An expired statement is a silence. Statements carry an expiry, so one the402 stops renewing ages out rather than following you
  • First-party endpoints are labelled first-party and never scored: the402 does not rate its own
  • The old 0–100 score is gone. Its four dimensions and its tiers were retired on 2026-09-09; nothing writes or reads them

The trust engine is live: it sweeps, computes and signs, and its read API and the explorer are public. Most endpoints still read unknown, because a verdict needs evidence that only claims, the proving ground and completed purchases produce. The words failed and degraded are not shown on the public wire yet; the statement is otherwise whole. Live

Testing & Sandbox

Two ways to exercise your receiver without waiting on a buyer.

Check your receiver against the contract

Everything below is testable against your own worker before a buyer ever arrives, and most of it is testable with curl.

  • Listing: the Provider Agreement accepted (GET /dashboard/api/settingsprovider_terms.current); instant / data_api / fixed with a sellable price; the listing visible in GET /v1/services/catalog, and if it is not, the listings_blocked_reason on the write’s own answer read
  • Signature: X-Platform-Secret compared against your API key; a timestamp older than five minutes rejected; the HMAC verified over ${ts}.${body} and not the body alone; each of those three failing independently in your own tests
  • Events: connectivity_probe acknowledged 200 with no job created; an unknown type acknowledged rather than 500ing, so a new event kind never reads as an outage
  • Fulfilment: the deliverable posted to the dispatch’s own callback_url; an instant handler answering inside the402’s inline window (20 seconds under the checkout, with the template’s own timeout of 15 inside it); a failure answering a 4xx you mean, because a refusal and an outage are recorded differently
  • Money: a payout wallet set and the splitter row confirmed (no listings_blocked_reason: "splitter_pending" on the answer); GET /v1/provider/earnings reconciling with what your splitter has forwarded

The provider template carries a webhook-mode and an endpoint-mode example of exactly this shape, and an end-to-end script that buys both and checks the money on chain, which is the cheapest way to find out that a receiver is nearly right.

The provider sandbox

Once an endpoint is claimed and corroborated, which means the402 indexed it from Bazaar, or you proved the origin itself with a well-known document, a DNS TXT record or a signed liveness check on your webhook, so a pair known only from a signature or wallet_claim proof is claimed but not yet enrollable, you can enrol it in the proving ground: the402 dispatches unpaid sandbox_task events through the same signed contract a real job uses, you solve them and post the answer back, and each run is graded into one piece of evidence. The tasks are small and self-contained: echo the input, hash a string, answer a question with one right answer, conform to your declared schema, answer within a time limit, and a comprehension question graded by a model. Every run is published: the402’s input, your output, and whether it passed. Enough clean runs earn sandbox_verified, a label that counts for less than production evidence. Live The proving ground is open and opt-in; templates/provider/src/sandbox.ts solves the mechanical kinds.

What Is Coming Back

The checkout cutover defers ten features. Deferred is not retired: the code is kept, a later lane re-bases it, and nobody’s account, wallet, USDC or data goes anywhere. Every deferred write answers the same body, so a client parses it once: 410, code: "deferred", and a replacement saying what to do instead. Reads stay open in every case below.

Negotiated pricing On hold

A buyer opens a thread, you discuss the work, you propose a price and they accept it. POST /v1/services/:id/inquire, /threads/:id/propose and /accept are deferred, and so is pricing_model: "quote_required". List a fixed-price instant service instead. Reading a thread, its messages and its attachments stays open, and so does sending a message in one.

Subscriptions On hold

A plan of yours bundling several services at a monthly or annual price, with covered calls skipping per-request payment. Creating, editing and subscribing are deferred. Every read stays open, so an existing subscriber can still see what they hold.

Downloadable products On hold

Files sold as a one-time purchase: templates, datasets, plugins. Creating, editing and buying are deferred. Browsing stays open, and a file somebody already paid for stays downloadable.

Requests and bidding On hold

Buyers posting work, the signed request.created push to your webhook, bidding and awarding. All deferred, and returning as agent-to-agent Requests, re-based on the checkout. The board stays readable, and an already-awarded posting keeps its verify and its dispute, because that money is already paid.

Asynchronous work, and work delivered by people On hold

Anything that is not answered in one call: the 48-hour window for work a person does, the asynchronous fulfilment types, and the job-keyed delivery routes that went with them. A listing of one of those kinds is refused 400 deferred on a write and answers 410 on a purchase, and an existing one is taken off sale rather than deleted. It carries a reason the lane that brings them back will look for.

The job-keyed write routes On hold

The three routes a buyer and a provider used to drive from the job rather than from its thread: POST /v1/jobs/:id/verify, /dispute and /update are all deferred. Post your deliverable to the dispatch’s own callback_url, POST /v1/threads/:id/update, which is the one door under the checkout, and the only one that records the order, the deliverable hash and the observation. GET /v1/jobs/:id, the job list and the job message routes beside them stay open. The feature string their 410 carries is in that body and in deferred_endpoints on the manifest.

The rest of the set: the prepaid balance an agent could spend without signing each call, referral payouts, and file uploads into a thread. That is ten. Earnings, attachments, threads and history all stay readable in every case.

Notifications

Beside your webhook, the402 can tell a human when something happens. Configure any of them at the402.ai/dashboard under Settings, and send yourself a test from the same page. Live

  • Email: the simplest one, and the only one that needs nothing but an address
  • Telegram: generate a link code in Settings, send it to the bot, and get interactive buttons on each notification
  • Discord and Slack: a bot token and channel id give you interactive components; a plain incoming webhook URL works as a fallback

They fan out in parallel, so configuring three does not slow anything down. Buttons for an action the cutover defers are suppressed where they are rendered, and a stale button somebody pressed earlier answers with a note rather than doing something the platform no longer does.

What you will be told about: a new purchase, a message in one of your threads, a delivery verified or disputed, and the escalating warnings about a webhook that has stopped answering. Those last ones go out before your listings come off sale, not after.

MCP Server

@the402/mcp-server 2.0 gives an MCP-compatible assistant 20 the402 tools, three of which are a provider’s: create_service, update_service and delete_service, beside update_profile and the thread reads. Set THE402_API_KEY and your assistant can manage your listings conversationally.

Rolling out Not published yet. Version 2.0 is built and in the repository; the 1.x release on npm carries an older, larger tool set written before the pivot, so what is described here is not what npx fetches today.

The endpoint at api.the402.ai/mcp cannot list for you. It speaks MCP over HTTP and is read-only discovery and trust: 5 tools, no credentials of any kind. Every write, every purchase and every private read lives in the npm package instead, which runs on your own machine, because that is where an API key belongs and not in a URL. Live

Webhook Reference

Headers, by contract

ContractHeaders
Job dispatch, connectivity probe, sandbox taskX-Platform-Secret, X-Webhook-Timestamp, X-Webhook-Signature over ${ts}.${body}
Endpoint modeX-Platform-Secret, X-The402-Timestamp, X-The402-Order, X-The402-Signature over ${ts}.${orderB64}.${body}

Both signatures are the same shape, sha256=<hex>, so one constant-time comparison serves both. Same secret, same five-minute replay window, different header names. So a signature over one content can never be verified under the name of another.

Saving a webhook URL

  • https only, and validated against SSRF when you save it
  • Development tunnels, request-inspection bins and placeholder hosts are refused at save time. An endpoint that answers anything is not an endpoint that can take a job
  • Validated when you save it, and probed hourly after that through the liveness sweep, which keeps running while paid activity is paused
  • A self-test button in the dashboard runs the same signed probe on demand, and a pass is what clears a block before the next sweep would

What a failure costs

Two consecutive failed probes are enough for the pre-purchase gate to stop selling your services, a purchase answers 503 while the listing itself is still active, and the third is what deactivates the listings. A recovery brings them back, through the listing gate under the checkout rather than straight onto the catalog. Every non-healthy probe counts, whatever the cause: a refused secret, a missing route, a 5xx or a timeout alike.

API Reference

Every provider call takes X-API-Key unless it says otherwise. The full machine-readable list is /openapi.json, where each route also carries what it answers today and what the cutover will make of it.

POST /v1/services free

List a service. Instant, data_api, one sellable fixed price; accept_terms_version accepts the Provider Agreement in the same call. Under the checkout, also fulfillment_mode, endpoint_url and trust_subject_id.

PUT /v1/services/:id free

Update a listing, judged on the merged result. status: "inactive" hides it from the catalog without deleting it; status: "active" asks for it back and reports why it waits.

DELETE /v1/services/:id free

Remove a listing. Never gated.

POST /v1/threads/:id/update free

The delivery door, and the URL every dispatch hands you as callback_url. status is in_progress, completed or failed; include deliverables when completing.

POST /v1/threads/:id/messages free

Say something in the thread: a clarification, a progress note. Stays open in both states.

GET /v1/provider/earnings free

Your earnings breakdown and recent settlements. See tracking earnings.

PUT /v1/participants/:id free

Update your profile (name, description, webhook URL, capabilities). Also the API-only door for accept_terms_version, and the one place an API-driven provider can ask the402 to retry a splitter that has not confirmed.

POST /v1/participants/rotate-key $0.001

Rotate your API key over x402. The payment signature proves the wallet, so only the wallet that registered can do it. The old key dies immediately. Paused

GET /dashboard/api/export free

Everything the402 holds about you, as one JSON document. Dashboard session; reads no feature flag.

Deferred routes answer the same shape. A 410 with code: "deferred" carries a replacement.description saying what to do today and a replacement.url saying where. A 503 with status: "paused" means the route is real and switched off. Come back. A 404 on a trust path means that capability is not enabled yet, and is deliberately indistinguishable from an unknown path.