{"version":"1.0","spec":"Trusteed Agent Checkout Guide","canonical_url":"https://trusteed.xyz/.well-known/agent-checkout-guide.json","human_readable_url":"https://trusteed.xyz/en/developers/agent-checkout","generated_at":"2026-09-09T00:00:00.000Z","canonical_scope":"Ordered, end-to-end path for an agent: which endpoint to call at each step, which credential it needs, and what to do with each error. For WHAT exists see mcp.json (tools) and trusteed-capabilities.json (rail states, signed). This document does not override either.","read_this_first":["Use the bucket endpoints, not the legacy alias. `/{store}/mcp` still answers, but it routes some tools through a different dispatcher than others; a flow that works there can fail halfway with no useful error.","`api.trusteed.xyz` and `trusteed.xyz` are the only hosts that serve this platform. Any `*.up.railway.app` endpoint is residual infrastructure: it answers `403 Invalid Host header` by design and will not be fixed — update your connector.","No payment rail settles funds in production today. Checkout here builds a cart and evaluates merchant policy and trust; it does not capture money. The authoritative per-rail state is the signed registry at /.well-known/trusteed-capabilities.json.","`demo-store` is a synthetic catalogue for exercising the protocol. Products, prices, stock and payments are fabricated."],"endpoints":{"discovery":{"url_template":"https://api.trusteed.xyz/{store_slug}/mcp/discovery","transport":"MCP Streamable HTTP (JSON-RPC 2.0)","auth":"none","tools":["browse_catalog_feed","browse_categories","compare_products","explore_store","get_merchant_profile","get_page_content","get_payment_methods","get_product_details","get_site_map","get_store_trust","get_tool_details","onx_get_inventory","run_scenario","search_docs","search_products","search_products_enriched","search_tools"],"notes":"Public and unauthenticated. Agent identity enforcement never blocks this bucket."},"checkout":{"url_template":"https://api.trusteed.xyz/{store_slug}/mcp/checkout","transport":"MCP Streamable HTTP (JSON-RPC 2.0)","auth":"OAuth 2.1 Bearer token (Authorization header)","tools":["apply_discount","attach_agent_identity","cancel_payment_mandate","complete_checkout","complete_visa_payment","create_cart","create_payment_mandate","get_shipping_rates","preview_checkout","process_agent_payment","select_shipping_option","ucp_add_items_to_checkout","ucp_cancel_checkout","ucp_complete_checkout","ucp_create_checkout","ucp_get_checkout","ucp_update_checkout","update_payment_mandate","verify_age_over_n","verify_legal_person_authorization","verify_residence_country"],"notes":"Idempotency-Key is required for the idempotent tools. Requests without credentials get 401 `no_credentials` — that is an auth failure, not a signature failure."},"customer":{"url_template":"https://api.trusteed.xyz/{store_slug}/mcp/customer","transport":"MCP Streamable HTTP (JSON-RPC 2.0)","auth":"OAuth 2.1 Bearer token bound to a customer","tools":["check_agent_consent","enroll_payment_method","get_acp_orders","onx_cancel_order","onx_create_return","onx_get_fulfillments","onx_get_orders","onx_get_returns"],"notes":"Order lookups, cancellations and returns for a known customer."},"legacy_alias":{"url_template":"https://api.trusteed.xyz/{store_slug}/mcp","status":"deprecated","notes":"Kept for existing integrations. Prefer the three buckets above: they have one dispatcher, one auth model and one error contract."},"rest_openapi":{"url":"https://api.trusteed.xyz/api/v1/openapi.json","auth":"X-Agent-Api-Key header","notes":"A DIFFERENT surface with a DIFFERENT credential. The MCP endpoints do not accept X-Agent-Api-Key, and this one does not accept the MCP Bearer token."}},"flow":[{"step":1,"goal":"Find merchants","call":"GET https://trusteed.xyz/.well-known/merchant-index.json","produces":"store slugs plus, per row, the MCP endpoint that actually serves that merchant (they are not all on the same host)","note":"Use the endpoint published for each row. Do not assume every merchant answers on the same host as the index."},{"step":2,"goal":"Find products","call":"tools/call `search_products` on the discovery endpoint","produces":"product ids to pass to `create_cart`; the field is `id` and it is NOT the SKU","note":"`get_product_details` takes the same id. Never invent ids."},{"step":3,"goal":"Judge the merchant","call":"tools/call `get_merchant_profile` on the discovery endpoint","produces":"trust score (0-100 scale, version 4.1), verification level and a verifyUrl that re-serves the same number signed","note":"Every discovery response also carries a `merchant_trust` block with the same figure. If two surfaces disagree, the signed one wins and it is a bug — report it."},{"step":4,"goal":"Build the cart","call":"tools/call `create_cart` on the CHECKOUT endpoint","requires":"OAuth 2.1 Bearer token","produces":"cart_id","note":"This is where the credential starts to matter. Sending it from step 4 onwards avoids a mid-flow 401."},{"step":5,"goal":"Shipping","call":"`get_shipping_rates`, then `select_shipping_option`","produces":"totals including shipping","note":"`get_shipping_rates` needs an address in `params`. Called with an empty object it returns `rates: []` and no error — an empty list here means you omitted the address, not that the merchant has no shipping."},{"step":6,"goal":"Review before paying","call":"`preview_checkout`","produces":"final total, the merchant policy verdict, and a state commitment binding what you were shown","note":"If the merchant's catalogue changed since you looked, this is where you are told, and you must re-confirm rather than proceed."},{"step":7,"goal":"Settle","call":"`complete_checkout`","requires":"Idempotency-Key","produces":"order status and, where the merchant has receipts enabled, a signed Trust Receipt","note":"Retry with the SAME Idempotency-Key. A retry with a new key is a second attempt, not a retry."}],"identity":{"summary":"Signing your requests is OPTIONAL for discovery and recommended for checkout. What is never required is that you sign — what matters is that if you do sign, the signature verifies.","profiles_accepted":[{"profile":"web-bot-auth","spec":"draft-meunier-web-bot-auth-architecture","note":"The profile ChatGPT and other crawler/agent fleets sign with. Publish your key at /.well-known/http-message-signatures-directory on the origin you name in `Signature-Agent`."},{"profile":"RFC 9421 without a tag","note":"Plain HTTP Message Signatures. Verified the same way."},{"profile":"agent-browser-auth / agent-payer-auth","note":"Visa Trusted Agent Protocol."}],"unsigned_requests":"Allowed. An unsigned request is `unverified`, never `spoofed`, and the production mode (`block_spoofed`) lets it through outside of merchant-specific policy.","unknown_profile":"A signature carrying a `tag` we do not know is `unverified` too — not rejected. It is simply not promoted to `verified`.","rejected":"Only a signature we can prove wrong is rejected: key not found in the directory you pointed at, signature that does not validate, replayed nonce, or expired beyond 300s. The 403 names which one in `error.data.reason`.","caveat":"Until 2026-09-09 a valid `web-bot-auth` signature was rejected as spoofed, because that profile tag was missing from our allowlist. If you integrated before that date and worked around it by stripping your signature, you can stop."},"errors":[{"code":"agent_signature_spoofed","http":403,"meaning":"Your signature was present and could be proven wrong. `error.data.reason` says how.","remedy":"Check `reason`. `agent_signature_key_not_found` → the keyid is not in the directory served from your `Signature-Agent` origin. `agent_signature_invalid` → the signature base does not match (most often a signed component we reconstruct differently, e.g. `@authority` behind your proxy). `signature_expired` → your `created` is older than 300s."},{"code":"no_credentials","http":401,"meaning":"No Authorization header on a bucket that requires one. This is NOT about signatures.","remedy":"Obtain an OAuth 2.1 token; see /.well-known/oauth-authorization-server."},{"code":"tool_not_found_in_bucket","http":404,"meaning":"The tool exists but not on the endpoint you called.","remedy":"Use the endpoint listed for that tool in `endpoints` above."},{"code":"PRODUCT_NOT_FOUND","meaning":"The product id does not exist in that store.","remedy":"Use the `id` returned by `search_products`. A SKU is not an id."},{"code":"idempotency_key_mismatch","http":422,"meaning":"Same Idempotency-Key, different arguments.","remedy":"A retry must repeat the request byte for byte. Changing the cart means a new key."}],"known_limitations":["UCP tools are dispatchable but do not appear in `tools/list`. Call them by name against the checkout endpoint, or use the UCP surface at /.well-known/ucp.","MCP elicitation (`elicitation/create`) is not reachable on any of our transports: they run without a session id, so the SDK never negotiates the capability. Tools that would elicit fall back to an out-of-band confirmation channel instead. Do not wait for an elicitation prompt.","The `demo-store` catalogue is synthetic and its payments are simulated."],"related_documents":{"tools":"https://trusteed.xyz/mcp.json","signed_capability_registry":"https://trusteed.xyz/.well-known/trusteed-capabilities.json","merchant_index":"https://trusteed.xyz/.well-known/merchant-index.json","agent_policy":"https://trusteed.xyz/.well-known/agent-policy.json","error_catalogue":"https://trusteed.xyz/en/developers/errors","oauth":"https://trusteed.xyz/.well-known/oauth-authorization-server","ucp":"https://trusteed.xyz/.well-known/ucp","llms_txt":"https://trusteed.xyz/llms.txt"}}