Skip to main content

Agentic Commerce

Gomry implements the Agentic Commerce Protocol (ACP), the open standard maintained by OpenAI and Stripe for letting AI agents discover products and complete purchases on a merchant’s own stack. There are two halves, and they are independent:

Catalog

A cross-organization, read-only feed of live public events. This is how an agent finds out an event exists.

Checkout

ACP checkout sessions. This is how an agent sells a ticket without sending the buyer to a browser.
A correct checkout is invisible without a catalog, and a catalog with no checkout still drives buyers to your event page. Most integrations start with the catalog.
Can’t hold a payment token? Most agents can’t — minting one needs a browser and a Stripe agent account. Every ticket type in the catalog carries a checkout_url that opens Gomry checkout with that tier preselected, so your agent can do the discovery and hand the buyer a link. No onboarding, no signing secret, works today. See Buying without a payment token.

What makes this surface different

Every other resource in this API resolves your key to exactly one organization and reads inside it. The commerce surface does not:
  • Catalog is cross-organization. One key returns live public events from every organizer on Gomry.
  • Checkout sells on another organizer’s behalf and takes payment against their Stripe account.
Because of that, both are off by default on every key, and checkout carries additional gates described below.

The purchase flow

1

Discover

GET /v1/catalog/events to page the catalog, then GET /v1/catalog/events/{event_id} for the one you intend to sell. The detail endpoint is the only place ticket_types and registration_questions are populated.
2

Create a session

POST /v1/checkout_sessions with items[].id set to a ticket type id from ticket_types[].id. The session comes back with line items, totals, and a status.
3

Resolve blockers

While status is not_ready_for_payment, read messages[]. Each error message says what is missing — a buyer name, a required registration answer, an out-of-stock line. Patch the session with POST /v1/checkout_sessions/{id} until status is ready_for_payment.
4

Complete

POST /v1/checkout_sessions/{id}/complete with a delegated payment token. On success the session reports completed and carries an order with a permalink_url your buyer can open.

Payment is token-only

No endpoint on this API accepts a card number, and none ever will. Payment reaches Gomry only as a delegated token — a Stripe Shared Payment Token in payment_data.token.
This is a hard architectural boundary, not a current limitation. Gomry has no raw-PAN code path; every paid flow is Stripe-hosted. Request bodies are validated strictly, so a body carrying an unexpected field such as card_number is rejected with a 400 rather than silently ignored. Practically, this means an agent platform must be able to mint a delegated payment token. An agent that holds only a raw card number cannot complete a Gomry checkout, and should send the buyer to the event url from the catalog instead.

Ids: what to pass where

The single most common integration error is passing an event id where a ticket type id belongs. Passing an event id as items[].id returns item_not_found.

Versioning

Send an API-Version header on every checkout request. This deployment implements:
A header naming a different version is refused with unsupported_api_version rather than served best-effort, so you never ship against fields we do not send. An absent header is accepted and treated as the current version. The ACP spec lists it as required and we recommend always sending it — but with exactly one version in service, refusing a partner mid-integration over a missing header helps nobody. Do not rely on that leniency: send the header, so the day a second version exists your client keeps getting the one it was built against. The catalog endpoints ignore this header entirely.

Access

The commerce surface is granted per partner. Contact support@gomry.com to be onboarded.
Catalog needs catalog: read on your API key. Checkout needs three independent things, all of which must be true:
  1. checkout: write on the key.
  2. The key id added to Gomry’s ACP partner allowlist — a deploy-time change, not a dashboard toggle.
  3. A signing secret issued to you, used to sign every request with a body.
The second and third exist because a scope can be granted by anyone with settings access, and a surface that sells arbitrary organizers’ tickets needs a gate that a misconfigured dashboard cannot open. See Scopes.

Request signing

Every checkout request with a body (create, update, complete) must carry two headers:
string
required
Base64 HMAC-SHA256 over {timestamp}.{raw_body}, using your signing secret.
string
required
RFC 3339. Must be within 5 minutes of Gomry’s clock, or the request is refused.
The timestamp and body are signed together so a captured signature cannot be replayed with a fresh timestamp.
Sign the raw body bytes you actually send. JSON.parse followed by JSON.stringify does not round-trip — key order, whitespace and number formatting all change — so signing a re-serialized object produces a signature that fails on a request that is otherwise perfectly authentic. Build the body string once, sign that string, and send that string.
GET and cancel carry no body and need no signature. They still require an allowlisted key, and should still send API-Version.
Signing a request
Secrets are rotated additively: during a cutover both the old and new secret verify, and the old one is retired once you confirm.

Headers

Checkout responses are always Cache-Control: no-store — they are per-buyer and must never be shared by a cache.

Errors

Checkout uses the ACP error envelope, which is different from the rest of this API:
type is one of invalid_request, processing_error, or service_unavailable. See Checkout Errors for every code and its status. The catalog endpoints use the standard Gomry error format.