Changelog
How the Mayarin API version axes work and what each revision changes.
The public API has two version axes. They do not replace each other.
Path — the breaking boundary
/v1 is the breaking boundary. A future /v2 is a new URL: a client opts in,
and the old surface stays up beside it. Every route in the API reference
is served under /v1.
Mayarin-Version — the date rev within v1
The Mayarin-Version header is the date revision within /v1. It covers
additive change: a new field, a new route, a new response shape that does not
break an existing client. The SDK pins it (packages/sdk/src/version.ts) so an
upgrade is a deliberate act, not a side effect of deploying the library.
Send the header to pin a revision:
Mayarin-Version: 2026-08-11Omit it and you receive the current revision. A pinned revision keeps working after additive changes ship; an additive change never removes a field or alters a type an existing client reads.
Unversioned routes
These stay at the root forever. A printed QR and a shared link encode them, so a version bump must never move them:
GET /checkout/:idand sub-routes — the hosted checkout page.GET /invoices/:id/view— the hosted invoice page.GET /health— the deployment probe.
A buyer page has no version. It renders whatever the current API serves.
Revisions
2026-08-11 — current
Initial public revision of the /v1 merchant API. Covers payment intents,
payments and refunds, quotes, catalog and carts, payment links, invoices,
provider webhooks, and the intentionally unversioned buyer surfaces.
This is still the current revision. Everything below shipped additively inside it — a new route or a new optional field never removes anything a pinned client reads, so none of it moved the date.
Additive since 2026-08-11
Agent payments (x402). /v1/x402/resources registers, lists and unlists an
endpoint you sell per request. The buyer-facing half is unversioned and keyless:
GET /x402/resources/:id/payment-required, POST …/verify, POST …/settle, the
GET /x402/resources and GET /x402/payables discovery indexes, and an MCP
server at POST /x402/mcp. See the guide.
A third execution path. executionPath accepts x402 beside
deposit-match and on-chain-contract, on payment intents, cart checkout and
invoice checkout, and reports back which path a payment took. See
execution paths.
Listing an obligation to agents. POST /v1/invoices/:id/list and
POST /v1/payment-links/:id/list, each with an /unlist twin. Nothing is listed
by default, and listing only affects whether something is found.
Refunds. POST /v1/payments/:id/refunds and GET /v1/payments/:id/refunds.
Idempotent: a repeated key returns the refund it made rather than issuing a
second one, and an omitted amount refunds everything still refundable.
Wider currency and rail coverage. More pricing currencies, EURC as a settlement and payer asset, and additional chains including Arc testnet. See currencies, assets and chains.
Subscriptions. /v1/subscriptions creates, lists, reads, pauses, resumes and cancels a recurring plan with a secret key. Every cycle is an invoice Mayarin issues and emails, and payments on it carry metadata.subscriptionId. The SDK exposes it as commerce.subscriptions. See the guide.
Retrying a failed payment. POST /v1/payments/:id/retry reopens a payment that failed after the payer’s funds arrived and settles it, re-signing an expired deposit order with the same terms. See payment lifecycle.
Invoice and receipt PDFs. GET /v1/payments/:id/invoice.pdf and GET /v1/payments/:id/receipt.pdf, drawn from the payment’s own records. The receipt carries the settlement proof.
Settlement per chain, and USDG. A merchant’s settlement asset can differ per chain, and each rail from GET /v1/payment-links/:id/rails reports its settlementAsset. USDG (Global Dollar) is a settlement and payer asset, on Arbitrum Sepolia and Robinhood Chain testnet. See currencies, assets and chains.
Hosted checkout URL on cart checkout. POST /v1/carts/checkout returns url, the absolute hosted checkout page for the new intent.
None of these require a client change. A client pinned to 2026-08-11 keeps
working and simply does not see the new fields.