Unpaid requests should fail closed (HTTP 402 with x402 metadata), not leak paid content.
x402 service listing quickstart
Use this when you run an x402-paid endpoint and you want agents to discover it with point-in-time evidence. Ontario listings are evidence-backed (readiness reports + integrity + history), not permanent safety guarantees. Agents should still run a fresh preflight policy check before spending.
Trust boundary
This workflow never asks for private keys or seed phrases. Treat listing + readiness as public evidence; do not submit raw wallet credentials, sensitive customer data, or secrets in listing metadata.
Step 1 — Generate a public readiness report
UI: /verify. API:
POST /api/verify/x402-readiness.
You will use the returned report_id as your proof link while iterating.
curl -X POST https://ontarioprotocol.com/api/verify/x402-readiness \
-H "Content-Type: application/json" \
-d '{"target_url":"https://example.com/api/paid-endpoint"}'
Step 2 — Reach grade=ready before you expect /discover inclusion
Publish /.well-known/x402.json and an OpenAPI document agents can parse.
Use a consistent endpoint URL, method, price, network, and owner fields.
Rerun verification after fixes to create a fresh public report ID.
Practical checklist: /proof/x402-discovery-listing-checklist.
Step 3 — Prepare listing JSON (validate locally and via API)
Ontario exposes the canonical payload contract as a strict JSON Schema:
/.well-known/x402-list-service.schema.json.
Use the free validator endpoint before you run the paid listing call.
{
"name": "Example Service",
"description": "Paid endpoint for agents",
"category": "data",
"endpoint": "https://example.com/api/paid",
"method": "POST",
"price_usdc": "0.01",
"network": "base",
"owner_url": "https://example.com",
"owner_contact": "ops@example.com",
"tags": ["x402", "ai-agent"]
}
curl -sS https://ontarioprotocol.com/api/x402/list-service/validate \
-H "Content-Type: application/json" \
-d '{"name":"Example Service","description":"Paid endpoint for agents","endpoint":"https://example.com/api/paid","method":"POST","price_usdc":"0.01","network":"base","owner_url":"https://example.com"}' | jq .
Step 4 — Rehearse the x402 listing flow in sandbox (no spend, no storage)
Use the sandbox rehearsal endpoint to test client behavior end-to-end. It still challenges with HTTP 402 on the first request, but settlement is simulated and the listing is not stored.
# 1) Probe: expect HTTP 402 + PAYMENT-REQUIRED (no listing stored yet)
curl -i -X POST https://ontarioprotocol.com/sandbox/api/x402/list-service \
-H "Content-Type: application/json" \
-d '{"name":"Example Service","description":"Paid endpoint for agents","endpoint":"https://example.com/api/paid","method":"POST","price_usdc":"0.01","network":"base","owner_url":"https://example.com"}'
The sandbox will accept any non-empty payload.signature field as “valid” to let you test client retry logic.
This is not a production x402 payment signature.
# 2) Retry with a simulated sandbox PAYMENT-SIGNATURE header (no keys; sandbox-only)
SIG="$(python3 - <<'PY'
import base64, json
payload = {
"x402Version": 1,
"scheme": "exact",
"network": "base-sandbox",
"payload": {
"signature": "sandbox-valid",
"authorization": {"from": "0xSandboxAgent"}
}
}
print(base64.b64encode(json.dumps(payload, separators=(",", ":"), sort_keys=True).encode("utf-8")).decode("ascii"))
PY
)"
curl -sS -X POST https://ontarioprotocol.com/sandbox/api/x402/list-service \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: ${SIG}" \
-d '{"name":"Example Service","description":"Paid endpoint for agents","endpoint":"https://example.com/api/paid","method":"POST","price_usdc":"0.01","network":"base","owner_url":"https://example.com"}' | jq .
Sandbox tutorial: /docs/agent-commerce-sandbox.
SDK examples: ontario_list_service.py ·
ontario-list-service.ts
Step 5 — Submit the paid listing (production)
The first request should return HTTP 402 (no listing stored yet). Then pay + retry using your x402 client against
POST /api/x402/list-service. If the stored readiness report grades
ready, the endpoint can become eligible for /discover's default filters.
curl -i -X POST https://ontarioprotocol.com/api/x402/list-service \
-H "Content-Type: application/json" \
-d '{"name":"Example Service","description":"Paid endpoint for agents","endpoint":"https://example.com/api/paid","method":"POST","price_usdc":"0.01","network":"base","owner_url":"https://example.com"}'
After submission, check /listings and filter-ready discovery via
/discover?grade=ready.
Next
Agents should treat the listing as a pointer to evidence, not a permission slip. Use
POST /api/agent/can-pay with strict policy, explicit budget,
and review rules before any wallet signs a payment payload.