ZanoraBetaDocs

Endpoints

The public keys that sign price challenges and receipts, the platform fee, and the health check. The health check and the fee need no API key; the public keys need any valid one.

GET/health

No auth. { status, time }. It says whether the gateway is up, nothing more. The current challenge-signing key id is signingKeyId on GET /v1/platform/public-key below.

GET/v1/fees

No auth. The seller fees: { takeRateBps, payoutFeeMicros, current: { takeRateBps, payoutFeeMicros, effectiveFrom, announcedAt }, upcoming: [ … ], noticeDays }. takeRateBps is the platform fee in force, in basis points (500 = 5%), taken from the seller's price. payoutFeeMicros is the flat fee per payout, in micro-dollars ("250000" = $0.25), taken from the amount paid out. upcoming lists announced changes, soonest first; each row carries both fees. An increase in either is always at least noticeDays (30) out; a decrease can take effect at once. A call pays the platform fee in force when it was paid for, a payout the payout fee in force when it was requested.

GET/v1/platform/public-key

Any valid API key. The ed25519 public key that signs 402 challenges: { publicKeyPem, signingKeyId }. signingKeyId identifies the key, it isn't a credential, and it changes only when the key is rotated. Clients check every challenge against it before signing a payment. The SDKs cache it.

GET/v1/platform/receipt-keys/:keyId

No API key needed. The public key for a receipt signing key: { keyId, publicKeyPem }. It's public so anyone holding a receipt can check it, including an x402 buyer with no Zanora account. Old keys stay available after rotation, so an old receipt can always be checked. Returns 404 for an unknown key id.

Verifying a signature yourself

Challenges, payment proofs and receipts are signed the same way:

  1. Take the object and remove signature and signingKeyId.
  2. Serialise it as canonical JSON: keys sorted at every level, no extra whitespace, amounts as strings.
  3. Verify the base64 signature with ed25519 against the public key.

verifyPayload(body, signature, publicKeyPem) in @zanora/core does this.