Skip to content

The open contract

The agent contract is open: another platform accepts the same agent payments by serving its six documents, and any buyer's agent buys there.

Three conformance levels, each holding the one before

Each level is proved by the open conformance suite. Filled: what a buyer's agent can do there.

Conformance levels

A seller claims a level in its offer card, and the conformance suite proves it. Each level holds the one before.

LevelA seller servesA buyer's agent can
cardA signed offer card at /.well-known/agents.json, its key list and signed receiptsCompare the seller on price, terms and proof; its person buys at Checkout
paidAlso the 402 challenge, payment in the call and a receipt per callPay per call from its budget, with no account at the seller
mandatedAlso mandate checks, binding quotes and a Key per buyer on requestBuy under a mandate, above a threshold by a person's approval, with a Key it never sees

npx apis.dev conform runs the suite against any host, on APIs.Dev or not, and prints each check with its result.

A seller outside APIs.Dev

The suite checks a seller that runs on its own servers, outside APIs.Dev.

Response
HTTP/1.1 200 OK
Content-Type: application/json
X-Cost: price=0, currency="USD"
X-Request-Id: req_0b6e3f2d91c47a85e3d6

{
  "host": "facts.example.com",
  "contract": ["1"],
  "claimed": "paid",
  "passed": "paid",
  "checks": [
    { "id": "card.signature", "ok": true },
    { "id": "card.keys", "ok": true },
    { "id": "challenge.offers", "ok": true },
    { "id": "payment.in-call", "ok": true },
    { "id": "receipt.output-digest", "ok": true },
    { "id": "mandate.verify", "ok": false,
      "says": "A revoked mandate was honoured after its status said revoked" }
  ]
}

That is POST https://apis.dev/v1/conformance with { "host": "facts.example.com" }. The seller passes paid and fails one check of mandated, so it claims paid.

What is published

The spec is published at https://apis.dev/contract/1 under an open licence, with a JSON Schema per document and test vectors for every signature.

PartWhat the spec fixes
The six documentsEach one's fields, its address and its signer: offer card, quote, mandate presentation, payment challenge, receipt, attestation
SigningEd25519 over a canonical JSON form, and the key lists at /.well-known/receipt-keys with their dates
HeadersMandate, Payment, Max-Cost, X-Cost, X-Receipt-Id and Contract-Version
CuresThe 402 with its offers, and the 401 and 403 a mandate check answers, each a Problem with a cure
RailsPayment in the call, a tab, a budget, and Checkout for a person, each with its proof

APIs.Dev is the reference implementation. Every product on it serves the top level from its first deploy, and declares nothing to do so.

Versions

Every document carries its contract version, and an offer card lists every version its seller serves.

A field is added in place and never retyped or removed. A breaking change is a new major, served beside the old one; the old one retires no sooner than 12 months after its successor.

A buyer names the version it speaks in Contract-Version. A seller that does not serve it answers 400 contract_unsupported, naming the versions it does.

Who trusts the result

A level a seller claims is a claim; a level the Verifier attests is proof.

The attestation is signed under the Verifier's own keys and copied into the offer card.

The buy side reaches every seller at paid or above, and a buyer's policy decides which attestations it requires.