Documentation
Agent Offers answers one question for buyer agents: what exactly can I buy from this seller right now, under which terms, and how? This page covers the offer schema, the seller API and the buyer API. Machine-readable versions: /openapi.json, /llms.txt.
Seller quick start
# 1. Free preview of structured input (nothing fetched or stored)
curl -X POST https://agentoffers.online/api/v1/offers/preview -H 'content-type: application/json' \
-d '{"url":"https://your-product.example","transaction":{"purchase_endpoint":"https://api.your-product.example/v1/run","payment_protocol":"x402"}}'
# 2. Create (paid, 0.049 USDC via x402): first call answers 402 with PAYMENT-REQUIRED;
# sign it with an x402 client and repeat with PAYMENT-SIGNATURE.
curl -i -X POST https://agentoffers.online/api/v1/offers -H 'content-type: application/json' -d @offer.json
# 3. Publish (free) with the management key from step 2
curl -X POST https://agentoffers.online/api/v1/offers/$ID/publish -H "authorization: Bearer $KEY"A complete TypeScript agent flow using @x402/fetch is published at /examples/agent-flow.ts.
What you can submit
Any combination of a URL and structured fields. With a URL, creation reads the page (schema.org JSON-LD, title, description, links), /llms.txt, /openapi.json (on the purchase endpoint's origin), /.well-known/agent-card.json, and any sources you list (docs, pricing, terms, OpenAPI, llms.txt, descriptor). It then sends one unpaid request to the purchase endpoint to observe its x402 payment requirement. Unpaid POST/PUT/PATCH probes are sent only to endpoints you declare as x402 or that your OpenAPI documents with a 402 response; use transaction.example_request if your endpoint validates the body before asking for payment. Agent Offers never pays a seller endpoint.
Price models: one_time per_request usage subscription fixed quote_required free . Amounts are exact decimal strings ("0.46", "20"); currencies are ISO 4217 codes or USDC/USDT/EURC/DAI/PYUSD/ETH/WETH/BTC/SOL; crypto prices need a CAIP-2 network (Base: eip155:8453). Keep your own wording in price.original. Limits: request 64 KiB, each JSON schema 16 KiB and depth 12.
Provenance
Every consequential field is an object { value, status, evidence?, note? }:
- VERIFIED Observed by Agent Offers at the cited time in a machine-readable source with matching semantics (x402 payment requirement, schema.org JSON-LD, OpenAPI, agent card) served from the seller domain or from the purchase endpoint itself. A snapshot, not a guarantee.
- SELLER_PROVIDED Supplied by the party that created the offer and not independently observed. Read together with seller.authority: at UNVERIFIED, that party has not demonstrated control of the seller domain.
- INFERRED Derived by deterministic rules from non-structured or third-party material (page titles, prose, link text). Never used for numeric price, currency, network or purchase endpoint.
- UNKNOWN Not established. Agent Offers never fills a commercial term by guessing.
If your statement contradicts a verified observation of a commercial term (for example your price vs. the x402 requirement), the value is withheld, the conflict is listed in commercial_terms.conflicts, and publication is blocked until you fix the endpoint or the submission. Prose like “from $20/month” is reported as a candidate and is never turned into a price. Language is never used to infer geography.
Quality report
report.ready_for_agents is true only when report.missing is empty (name, price or quote model, billing model, purchase path, no unresolved conflicts, not expired, production network). warnings list concrete gaps (refund terms, schemas, service area, authority…). There is no score.
Lifecycle and freshness
DRAFT → PUBLISHED ⇄ PAUSED → WITHDRAWN. Drafts are never public. A paid PATCH (JSON merge patch; {} refreshes every source) creates a new draft revision; the published revision changes only when you publish again. Terms are CURRENT for freshness_days (default 30, max 90) after they were last confirmed, then STALE; after valid_until they are EXPIRED. Status is computed on every read and CDN copies never outlive the next status change. Pause and withdrawal reach every cached copy within 60 seconds.
Seller authority
New offers are UNVERIFIED: their creator has not shown control of the seller domain. To reach DOMAIN_CONFIRMED, publish the challenge returned at creation as a TXT record at _agent-offers.<domain> or as a line in https://<domain>/.well-known/agent-offers-verification.txt, then call POST /api/v1/offers/{id}/authority with {"method":"dns_txt","domain":"<domain>"}. Confirmation lasts 180 days. It proves control of DNS or the web server, not legal identity or ownership. SIGNED_BY_SELLER is reserved and not issued yet. External domain-control proofs can plug in as additional authority methods without changing the offer format.
Management key
Creation returns management_key (aom_…) once. It is required for publish, pause, withdraw, revise, authority checks and the private view (GET /api/v1/offers/{id}/manage). Rotate it with POST /api/v1/offers/{id}/rotate-key; the old key stops working immediately. Public responses never contain it.
Buyer agents
GET https://agentoffers.online/api/v1/offers/{id} # full document + status (free)
GET https://agentoffers.online/api/v1/offers?domain=seller.com # published, CURRENT offers for a domain
GET https://agentoffers.online/api/v1/offers?capability=translation&authority=DOMAIN_CONFIRMED
POST https://agentoffers.online/api/v1/documents/verify # check a self-hosted copy's signatureCheck status.actionable and status.freshness, prefer VERIFIED fields, and compare the live x402 requirement with the offer before paying the seller. Agent Offers is never in the payment path.
Export and self-hosting
GET /api/v1/offers/{id}/artifact returns the signed agent-offer.json. GET /api/v1/offers/collection?domain=… returns a signed collection of your DOMAIN_CONFIRMED offers to host at /.well-known/agent-offers.json on your own domain. These are Agent Offers formats (schema 1.0), not an industry standard. Signatures: Ed25519 over the RFC 8785 canonical JSON without signature; keys at /.well-known/agent-offers-keys.json.
Retrieval and safety
User agent AgentOffers/1.0. Only public http(s) addresses (every DNS answer is checked and the connection is pinned to it), at most 4 redirects, 1 MB per source after decompression, 7 s per request, at most 9 sources per revision. Retrieved content is data; no language model is used anywhere, so page text cannot instruct the service.
Errors
JSON {"error":{"code","message"}}. Branch on code: invalid_offer (422, with errors[]), invalid_request, unauthorized, offer_not_found, offer_not_ready, offer_not_current, lifecycle_conflict, concurrent_revision, payment_reused, settlement_failed, settlement_unknown, rate_limited, not_configured.