API reference
Every machine-facing route this site serves — parameters, responses, the error model and authentication — rendered from the OpenAPI 3.1 document.
Overview
Discover events, read prices and availability, open a checkout the buyer completes — and, with an organizer’s consent, manage their events.
The machine-facing surface of https://ticketing-staging.softjourn.if.ua. Anonymous reads (the catalogue, markdown renditions, discovery documents), the UCP checkout, and the MCP connectors.
Versioning
This is API version 1. Every operation accepts the API-Version request header and answers with the version it served in the same header. The UCP paths are fixed by that protocol and are versioned by the ucp.version field in their bodies; everything else is versioned here. A breaking change ships as a new value of API-Version; the previous value keeps working for at least 90 days.
Deprecation
A deprecated operation or version announces itself on every response with the RFC 9745 Deprecation header (the date it was deprecated) and the RFC 8594 Sunset header (the date it stops answering), plus a Link; rel="deprecation" to the replacement. Nothing is deprecated today. The human-readable policy is at /developers#versioning.
Errors
Every non-2xx answer outside the UCP envelope is an RFC 9457 application/problem+json document (Problem below) with a stable code. The UCP routes answer in their protocol’s envelope (UcpError). The edge gateway’s 402 is a Problem too.
Limits
Verified agents (Web Bot Auth) have a per-key token bucket at the edge and receive 429 with Retry-After when it is exhausted. Anonymous holds are capped per call and per cart. Nothing here reserves inventory except a UCP checkout session, and it expires.
Guides, the quickstart and the sandbox are on the developer portal.
Discovery
Documents that say what exists here.
GET/apiMachine-readable entry point
Names every discovery document and agent resource on this origin. Where the edge gateway is configured with a tariff this exact path is priced (x402); the 402 challenge is authoritative.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The index. — application/json →ApiIndex402Payment required (edge tariff). — application/problem+json →Problem404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/openapi.jsonThis document
OpenAPI 3.1.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/vnd.oai.openapi+json; charset=utf-8404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/.well-known/agent-skills/index.jsonAgent Skills index
Discover instructions for public MCP handoff, organizer management and Markdown reading.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/.well-known/agent-skills/{name}/SKILL.mdRead an Agent Skill
Markdown instructions with YAML name and description front matter.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
name required | path | string · one of: find-and-hand-off, organizer-management, read-catalogue-as-markdown | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The skill. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/llms.txtWhat this site is and when an agent should use it
llms.txt (llmstxt.org): the one-page orientation, with a "When to use this" section and every entry point.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200Markdown. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/.well-known/api-catalogRFC 9727 API catalogue
An RFC 9264 linkset naming the APIs this origin serves. The per-organizer catalogue at /{organizer}/.well-known/api-catalog names that organizer’s endpoints.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/linkset+json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/.well-known/acp.jsonACP platform discovery
The platform’s ACP document. It claims no service: each organizer is a seller with its own document at /{organizer}/.well-known/acp.json.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/.well-known/ard.jsonAgent-readiness manifest
ARD manifest.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/.well-known/ai-catalog.jsonAI catalogue manifest
The AI catalogue manifest for this origin.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/{organizer}/.well-known/api-catalogAn organizer’s RFC 9727 catalogue
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The linkset. — application/linkset+json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
Markdown for agents
Page content negotiated by Accept: text/markdown.
GET/api/agent-mdThe platform catalogue as markdown
The same content as GET / with Accept: text/markdown: what this site is, when to use it, the listed organizers and the first page of events. Takes the same query string as the page.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The rendition. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/api/agent-md/developersThe developer portal as markdown
The same content as GET /developers with Accept: text/markdown.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The rendition. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/api/agent-md/pricingThe pricing page as markdown
The same content as GET /pricing with Accept: text/markdown.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The rendition. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/api/agent-md/{organizer}An organizer’s catalogue as markdown
The same content as GET /{organizer} with Accept: text/markdown. Built from the public models, never by converting HTML.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The rendition. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/api/agent-md/{organizer}/{event}An event page as markdown
The same content as GET /{organizer}/{event} with Accept: text/markdown, including the ticketTypePriceId of every tier so a purchase link can be built without a second request.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
event required | path | string | Event slug. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The rendition. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
Catalogue
Anonymous reads over the platform catalogue.
GET/api/webmcp/eventsSearch the platform catalogue
The JSON behind the page-embedded WebMCP search_events tool. Anonymous; returns only what organizers chose to list.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
query | query | string | — |
city | query | string | — |
organizer | query | string | — |
category | query | string | — |
from | query | string | — |
to | query | string | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200Matching events. — application/json400Unparseable date. — application/problem+json →Problem404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/api/webmcp/eventOne event, for the page-embedded agent
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | query | string | — |
slug required | query | string | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The event. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
UCP
Universal Commerce Protocol — catalogue.
GET/.well-known/ucpUCP platform profile
The origin-root Universal Commerce Protocol profile — a truthful stub; each organizer publishes the real one.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/api/ucp/schemas/selection-handoff.jsonSelection-handoff capability schema
JSON Schema of the ?sel= purchase-link grammar.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The document. — application/schema+json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
GET/{organizer}/.well-known/ucpAn organizer’s UCP profile
Declares the capabilities the endpoints below implement (catalog.search, catalog.lookup, checkout, selection_handoff).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The profile. — application/json404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
POST/{organizer}/api/ucp/catalog/searchSearch an organizer’s events
UCP dev.ucp.shopping.catalog.search. Anonymous. Prices are all-in; a variant id is a ticketTypePriceId.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Request body
application/json
Responses
200Products and a cursor. — application/json →UcpSearchResponse400Malformed body. — application/json →UcpError404Unknown organizer. — application/json →UcpError
POST/{organizer}/api/ucp/catalog/lookupResolve product ids
UCP dev.ucp.shopping.catalog.lookup. Anonymous.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Request body (required)
application/json
Responses
200The products that resolved; unresolved ids appear inmessages. — application/json →UcpLookupResponse400Malformed body. — application/json →UcpError404Unknown organizer. — application/json →UcpError
UCP checkout
Universal Commerce Protocol — checkout sessions.
POST/{organizer}/api/ucp/checkout-sessionsOpen a checkout session
UCP dev.ucp.shopping.checkout. Holds inventory for the session’s lifetime; the buyer pays at continue_url in their own browser — no agent path accepts a payment. Requires UCP-Agent, Request-Id and Idempotency-Key.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
UCP-Agent required | header | string | RFC 8941 dictionary with profile= naming the agent’s own HTTPS /.well-known/ucp URI. |
Request-Id required | header | string · max 255 chars | Caller-chosen id, echoed back. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Request body (required)
application/json → UcpCheckoutRequest
Responses
201The session. — application/json →UcpCheckoutResponse400Malformed request —codesays which header or field. — application/json →UcpError404Unknown organizer or session. — application/json →UcpError409The checkout can no longer proceed (checkout_conflict). — application/json →UcpError503Checkout storage unavailable — retry with the same Idempotency-Key. — application/json →UcpError
GET/{organizer}/api/ucp/checkout-sessions/{id}Read a checkout session
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
UCP-Agent required | header | string | RFC 8941 dictionary with profile= naming the agent’s own HTTPS /.well-known/ucp URI. |
Request-Id required | header | string · max 255 chars | Caller-chosen id, echoed back. |
Responses
200The session. — application/json →UcpCheckoutResponse400Malformed request —codesays which header or field. — application/json →UcpError404Unknown organizer or session. — application/json →UcpError409The checkout can no longer proceed (checkout_conflict). — application/json →UcpError503Checkout storage unavailable — retry with the same Idempotency-Key. — application/json →UcpError
PUT/{organizer}/api/ucp/checkout-sessions/{id}Update a checkout session
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
UCP-Agent required | header | string | RFC 8941 dictionary with profile= naming the agent’s own HTTPS /.well-known/ucp URI. |
Request-Id required | header | string · max 255 chars | Caller-chosen id, echoed back. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Request body (required)
application/json → UcpCheckoutRequest
Responses
200The session. — application/json →UcpCheckoutResponse400Malformed request —codesays which header or field. — application/json →UcpError404Unknown organizer or session. — application/json →UcpError409The checkout can no longer proceed (checkout_conflict). — application/json →UcpError503Checkout storage unavailable — retry with the same Idempotency-Key. — application/json →UcpError
POST/{organizer}/api/ucp/checkout-sessions/{id}/cancelCancel a checkout session and release its holds
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
UCP-Agent required | header | string | RFC 8941 dictionary with profile= naming the agent’s own HTTPS /.well-known/ucp URI. |
Request-Id required | header | string · max 255 chars | Caller-chosen id, echoed back. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Responses
200The cancelled session. — application/json →UcpCheckoutResponse400Malformed request —codesays which header or field. — application/json →UcpError404Unknown organizer or session. — application/json →UcpError409The checkout can no longer proceed (checkout_conflict). — application/json →UcpError503Checkout storage unavailable — retry with the same Idempotency-Key. — application/json →UcpError
POST/{organizer}/api/ucp/checkout-sessions/{id}/completeComplete a checkout session
Places the order for a session that is ready_for_complete. A paid order still completes payment at continue_url.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
UCP-Agent required | header | string | RFC 8941 dictionary with profile= naming the agent’s own HTTPS /.well-known/ucp URI. |
Request-Id required | header | string · max 255 chars | Caller-chosen id, echoed back. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Request body
application/json → UcpCheckoutRequest
Responses
200The session, withorderwhen placed. — application/json →UcpCheckoutResponse400Malformed request —codesays which header or field. — application/json →UcpError404Unknown organizer or session. — application/json →UcpError409The checkout can no longer proceed (checkout_conflict). — application/json →UcpError503Checkout storage unavailable — retry with the same Idempotency-Key. — application/json →UcpError
Authentication
GET/auth.mdHow to authenticate, in prose
RFC 9728 → RFC 8414 → RFC 7591 → authorization code + PKCE, with the scope vocabulary. 404 until the deployment names its OAuth issuer.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200Markdown. — text/markdown404No such route or resource. — application/problem+json →Problem405The route exists; the method does not. — application/problem+json →Problem429Budget exhausted — waitRetry-Afterseconds. — application/problem+json →Problem5XXUnexpected failure. Retry with the same Idempotency-Key where one applies. — application/problem+json →Problem
MCP
Model Context Protocol connectors (on the API origin).
POST/mcpPublic MCP connector (buyers)
Read-only, anonymous: search events, read one, mint a purchase link.
Request body (required)
application/json
Responses
200A JSON-RPC 2.0 response, or an event stream. — application/json, text/event-stream401No or invalid bearer token;WWW-Authenticatenames the RFC 9728 metadata.403Wrong realm, impersonated session, or a scope the grant does not carry (insufficient_scope).
POST/mcp/organizerOrganizer MCP connector (staff)
Every management tool the authenticated organizer may use. Write tools are listed only for a grant that carries organizer:write.
Request body (required)
application/json
Responses
200A JSON-RPC 2.0 response, or an event stream. — application/json, text/event-stream401No or invalid bearer token;WWW-Authenticatenames the RFC 9728 metadata.403Wrong realm, impersonated session, or a scope the grant does not carry (insufficient_scope).
ACP
GET/{organizer}/.well-known/acp.jsonAn organizer’s ACP seller document
ACP discovery for one seller: api_base_url is /{organizer}/api, the one service is checkout. Payment handlers are negotiated per session.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version | header | string · one of: 1 | Requested API version. Omitted means the current version (1). The response carries the version served in the same header. |
Responses
200The discovery document. — application/json404Unknown organizer. — application/json →AcpError
ACP checkout
POST/{organizer}/api/checkout_sessionsCreate an ACP checkout session
Holds the tickets for the session’s lifetime under the per-person cap. Item ids are the UCP catalogue variant ids (ticketTypePriceId). Requires Authorization: Bearer, API-Version and Idempotency-Key; the session is bound to the bearer token.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
API-Version required | header | string · one of: 2026-04-17 | The ACP release the caller speaks. Supported: 2026-04-17. |
Request-Id | header | string · max 255 chars | Caller-chosen id, echoed back. |
Timestamp | header | string (date-time) | RFC 3339, within ±300 s of our clock. Required with Signature. |
Signature | header | string | base64url(HMAC-SHA256(signing secret, Timestamp + "." + JCS(body))) — RFC 8785 canonical JSON; a request with no body signs Timestamp + ".". Required unless the agent was registered without signing. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Request body (required)
application/json
Responses
201The session. — application/json →AcpCheckoutSession400Malformed request, missing header, or invalid field (paramnames it). — application/json →AcpError401Not a registered agent, or the request is not signed as it must be.code: unauthorized | invalid_api_key | revoked | signature_required | invalid_timestamp | stale_timestamp | invalid_signature. — application/json →AcpError404Unknown session, or one created under another token. — application/json →AcpError405Cancel of a completed or canceled session. — application/json →AcpError409Conflict: sold out, cap reached, session not editable, or an idempotent request in flight. — application/json →AcpError413Request body over 256 KiB. — application/json →AcpError422Idempotency-Key reused with a different body. — application/json →AcpError503Checkout temporarily unavailable. — application/json →AcpError
GET/{organizer}/api/checkout_sessions/{id}Read an ACP checkout session
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version required | header | string · one of: 2026-04-17 | The ACP release the caller speaks. Supported: 2026-04-17. |
Request-Id | header | string · max 255 chars | Caller-chosen id, echoed back. |
Timestamp | header | string (date-time) | RFC 3339, within ±300 s of our clock. Required with Signature. |
Signature | header | string | base64url(HMAC-SHA256(signing secret, Timestamp + "." + JCS(body))) — RFC 8785 canonical JSON; a request with no body signs Timestamp + ".". Required unless the agent was registered without signing. |
Responses
200The session. — application/json →AcpCheckoutSession400Malformed request, missing header, or invalid field (paramnames it). — application/json →AcpError401Not a registered agent, or the request is not signed as it must be.code: unauthorized | invalid_api_key | revoked | signature_required | invalid_timestamp | stale_timestamp | invalid_signature. — application/json →AcpError404Unknown session, or one created under another token. — application/json →AcpError405Cancel of a completed or canceled session. — application/json →AcpError409Conflict: sold out, cap reached, session not editable, or an idempotent request in flight. — application/json →AcpError413Request body over 256 KiB. — application/json →AcpError422Idempotency-Key reused with a different body. — application/json →AcpError503Checkout temporarily unavailable. — application/json →AcpError
POST/{organizer}/api/checkout_sessions/{id}Update an ACP checkout session
An absent line_items leaves the holds alone; an absent buyer field leaves that field alone.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version required | header | string · one of: 2026-04-17 | The ACP release the caller speaks. Supported: 2026-04-17. |
Request-Id | header | string · max 255 chars | Caller-chosen id, echoed back. |
Timestamp | header | string (date-time) | RFC 3339, within ±300 s of our clock. Required with Signature. |
Signature | header | string | base64url(HMAC-SHA256(signing secret, Timestamp + "." + JCS(body))) — RFC 8785 canonical JSON; a request with no body signs Timestamp + ".". Required unless the agent was registered without signing. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Request body (required)
application/json
Responses
200The session. — application/json →AcpCheckoutSession400Malformed request, missing header, or invalid field (paramnames it). — application/json →AcpError401Not a registered agent, or the request is not signed as it must be.code: unauthorized | invalid_api_key | revoked | signature_required | invalid_timestamp | stale_timestamp | invalid_signature. — application/json →AcpError404Unknown session, or one created under another token. — application/json →AcpError405Cancel of a completed or canceled session. — application/json →AcpError409Conflict: sold out, cap reached, session not editable, or an idempotent request in flight. — application/json →AcpError413Request body over 256 KiB. — application/json →AcpError422Idempotency-Key reused with a different body. — application/json →AcpError503Checkout temporarily unavailable. — application/json →AcpError
POST/{organizer}/api/checkout_sessions/{id}/completeComplete an ACP checkout session — and pay with a shared payment token
Places the order. With payment_data.handler_id = "card_tokenized" and instrument.credential = { type: "spt", token: "spt_…" } (a Stripe shared payment token scoped to the handler’s merchant_id) the order is charged and confirmed in the call: status: completed. A decline answers ready_for_payment + payment_declined (send a new token); a card that needs 3-D Secure, or payment_data without an instrument, answers requires_escalation + continue_url for the buyer to pay in their browser.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version required | header | string · one of: 2026-04-17 | The ACP release the caller speaks. Supported: 2026-04-17. |
Request-Id | header | string · max 255 chars | Caller-chosen id, echoed back. |
Timestamp | header | string (date-time) | RFC 3339, within ±300 s of our clock. Required with Signature. |
Signature | header | string | base64url(HMAC-SHA256(signing secret, Timestamp + "." + JCS(body))) — RFC 8785 canonical JSON; a request with no body signs Timestamp + ".". Required unless the agent was registered without signing. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Request body (required)
application/json
Responses
200The session, withorderonce placed. — application/json →AcpCheckoutSession400Malformed request, missing header, or invalid field (paramnames it). — application/json →AcpError401Not a registered agent, or the request is not signed as it must be.code: unauthorized | invalid_api_key | revoked | signature_required | invalid_timestamp | stale_timestamp | invalid_signature. — application/json →AcpError404Unknown session, or one created under another token. — application/json →AcpError405Cancel of a completed or canceled session. — application/json →AcpError409Conflict: sold out, cap reached, session not editable, or an idempotent request in flight. — application/json →AcpError413Request body over 256 KiB. — application/json →AcpError422Idempotency-Key reused with a different body. — application/json →AcpError503Checkout temporarily unavailable. — application/json →AcpError
POST/{organizer}/api/checkout_sessions/{id}/cancelCancel an ACP checkout session and release its holds
Parameters
| Name | In | Type | Description |
|---|---|---|---|
organizer required | path | string | The organizer’s slug — the first path segment of their storefront. |
id required | path | string | — |
API-Version required | header | string · one of: 2026-04-17 | The ACP release the caller speaks. Supported: 2026-04-17. |
Request-Id | header | string · max 255 chars | Caller-chosen id, echoed back. |
Timestamp | header | string (date-time) | RFC 3339, within ±300 s of our clock. Required with Signature. |
Signature | header | string | base64url(HMAC-SHA256(signing secret, Timestamp + "." + JCS(body))) — RFC 8785 canonical JSON; a request with no body signs Timestamp + ".". Required unless the agent was registered without signing. |
Idempotency-Key required | header | string · max 255 chars | Required on every mutation; a replay returns the original answer for 24 hours. |
Responses
200The canceled session. — application/json →AcpCheckoutSession400Malformed request, missing header, or invalid field (paramnames it). — application/json →AcpError401Not a registered agent, or the request is not signed as it must be.code: unauthorized | invalid_api_key | revoked | signature_required | invalid_timestamp | stale_timestamp | invalid_signature. — application/json →AcpError404Unknown session, or one created under another token. — application/json →AcpError405Cancel of a completed or canceled session. — application/json →AcpError409Conflict: sold out, cap reached, session not editable, or an idempotent request in flight. — application/json →AcpError413Request body over 256 KiB. — application/json →AcpError422Idempotency-Key reused with a different body. — application/json →AcpError503Checkout temporarily unavailable. — application/json →AcpError
Security schemes
Anonymous reads need no credentials. The schemes below apply where an operation names them; the step-by-step flow is in auth.md.
agentSignature http · Signature
Optional: Web Bot Auth (RFC 9421 HTTP Message Signatures, Ed25519) with a Signature-Agent directory this deployment allowlists. Identity, not authorization — an unsigned request is never refused for being unsigned.
oauth2 oauth2
Our own authorization server (RFC 8414 metadata at https://ticketing-staging.softjourn.if.ua/.well-known/oauth-authorization-server, RFC 7591 dynamic registration, PKCE S256 only, public clients). A token is pinned to ONE organizer at consent and narrowed to the scopes requested; a refresh keeps the scope and never widens it.
organizer:read— Read the organizer’s events, venues, seating and readiness — nothing changes.organizer:write— Create and change the organizer’s events, venues, maps, prices and schedules.
Schemas
Every named body shape the operations above refer to.
ProblemRFC 9457 problem details. Every non-2xx answer outside the UCP envelope is one of these; `code` is the stable machine-readable identifier and `hint` says what to do instead.
{
"type": "object",
"description": "RFC 9457 problem details. Every non-2xx answer outside the UCP envelope is one of these; `code` is the stable machine-readable identifier and `hint` says what to do instead.",
"required": [
"type",
"title",
"status",
"detail",
"code",
"requestId"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Dereferenceable explanation of the error class."
},
"title": {
"type": "string"
},
"requestId": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{1,128}$",
"description": "Correlation ID echoed in X-Request-Id."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable, specific to this occurrence."
},
"instance": {
"type": "string",
"description": "The request path that produced the problem."
},
"code": {
"type": "string",
"enum": [
"not_found",
"method_not_allowed",
"bad_request",
"unauthorized",
"forbidden",
"conflict",
"rate_limited",
"internal"
],
"description": "Stable, machine-readable. Match on this, never on `detail`."
},
"hint": {
"type": "string",
"description": "The next request that will work — a URL or a sentence."
}
}
}UcpErrorThe UCP error envelope — the shape the UCP routes use instead of `Problem`.
{
"type": "object",
"description": "The UCP error envelope — the shape the UCP routes use instead of `Problem`.",
"required": [
"ucp",
"code",
"content"
],
"properties": {
"ucp": {
"type": "object",
"required": [
"version",
"status"
],
"properties": {
"version": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"error"
]
}
}
},
"code": {
"type": "string",
"description": "Stable, machine-readable (e.g. `missing_request_id`, `invalid_ucp_agent`, `checkout_conflict`)."
},
"content": {
"type": "string"
}
}
}UcpMessage
{
"type": "object",
"required": [
"type",
"code",
"content"
],
"properties": {
"type": {
"type": "string",
"enum": [
"error",
"warning",
"info"
]
},
"code": {
"type": "string"
},
"content": {
"type": "string"
},
"severity": {
"type": "string",
"enum": [
"recoverable",
"unrecoverable"
]
}
}
}UcpPrice
{
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "number",
"description": "Minor units of `currency` (its smallest unit), all in — the total the buyer pays, every price component included. The parts are in the variant’s `metadata.price_components`, whose `gross_minor` sum to this amount."
},
"currency": {
"type": "string",
"description": "ISO 4217."
}
}
}UcpVariant
{
"type": "object",
"required": [
"id",
"title",
"price",
"availability"
],
"properties": {
"id": {
"type": "string",
"description": "The `ticketTypePriceId` — the id the purchase link and a checkout line take."
},
"title": {
"type": "string"
},
"description": {
"type": "object",
"properties": {
"plain": {
"type": "string"
}
}
},
"price": {
"$ref": "#/components/schemas/UcpPrice"
},
"availability": {
"type": "object",
"required": [
"available",
"status"
],
"properties": {
"available": {
"type": "boolean"
},
"status": {
"type": "string"
}
}
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "`price_components` ({kind, label, net_minor, tax_minor, gross_minor}[]) is the breakdown of `price.amount`; `face_value_minor` / `booking_fee_minor` are the same parts by kind, kept for existing readers. `tax_finality` is `final` when `price.amount` is what checkout charges."
}
}
}UcpProduct
{
"type": "object",
"required": [
"id",
"handle",
"title",
"url",
"price_range",
"variants"
],
"properties": {
"id": {
"type": "string",
"description": "`evt:{organizer}/{slug}`"
},
"handle": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "object",
"properties": {
"plain": {
"type": "string"
}
}
},
"url": {
"type": "string",
"format": "uri",
"description": "The event page — where a buyer completes the purchase."
},
"price_range": {
"type": "object",
"properties": {
"min": {
"$ref": "#/components/schemas/UcpPrice"
},
"max": {
"$ref": "#/components/schemas/UcpPrice"
}
}
},
"options": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"variants": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UcpVariant"
}
},
"metadata": {
"type": "object",
"additionalProperties": true
}
}
}UcpSearchResponse
{
"type": "object",
"required": [
"ucp",
"products",
"pagination"
],
"properties": {
"ucp": {
"type": "object",
"required": [
"version"
],
"properties": {
"version": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"error"
]
}
}
},
"products": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UcpProduct"
}
},
"pagination": {
"type": "object",
"required": [
"has_next_page"
],
"properties": {
"has_next_page": {
"type": "boolean"
},
"cursor": {
"type": "string",
"description": "Present exactly when `has_next_page` is true."
},
"total_count": {
"type": "integer"
}
}
},
"messages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UcpMessage"
}
}
}
}UcpLookupResponse
{
"type": "object",
"required": [
"ucp",
"products"
],
"properties": {
"ucp": {
"type": "object",
"required": [
"version"
],
"properties": {
"version": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"error"
]
}
}
},
"products": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UcpProduct"
}
},
"messages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UcpMessage"
}
}
}
}UcpBuyer
{
"type": "object",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"phone_number": {
"type": "string"
}
}
}UcpCheckoutRequest
{
"type": "object",
"properties": {
"line_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"item": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "A variant id from the catalogue."
}
}
},
"quantity": {
"type": "integer",
"minimum": 1
}
}
}
},
"buyer": {
"$ref": "#/components/schemas/UcpBuyer"
},
"payment": {
"type": "object",
"additionalProperties": true
}
}
}UcpCheckoutResponse
{
"type": "object",
"required": [
"ucp",
"id",
"line_items",
"status",
"currency",
"totals",
"links",
"expires_at"
],
"properties": {
"ucp": {
"type": "object",
"additionalProperties": true
},
"id": {
"type": "string"
},
"line_items": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"item",
"quantity",
"totals"
],
"properties": {
"id": {
"type": "string"
},
"item": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"price": {
"type": "number"
}
}
},
"quantity": {
"type": "integer"
},
"totals": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"amount": {
"type": "number"
}
}
}
}
}
}
},
"buyer": {
"$ref": "#/components/schemas/UcpBuyer"
},
"status": {
"type": "string",
"enum": [
"incomplete",
"requires_escalation",
"ready_for_complete",
"complete_in_progress",
"completed",
"canceled"
]
},
"currency": {
"type": "string"
},
"totals": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"amount": {
"type": "number"
},
"display_text": {
"type": "string"
}
}
}
},
"links": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
}
}
}
},
"messages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UcpMessage"
}
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"continue_url": {
"type": "string",
"format": "uri",
"description": "Where the BUYER pays. No agent path accepts a payment."
},
"order": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"permalink_url": {
"type": "string",
"format": "uri"
}
}
}
}
}AcpErrorACP protocol-level error: the shape the ACP routes use instead of `Problem`.
{
"type": "object",
"description": "ACP protocol-level error: the shape the ACP routes use instead of `Problem`.",
"required": [
"type",
"code",
"message"
],
"properties": {
"type": {
"type": "string",
"enum": [
"invalid_request",
"processing_error",
"service_unavailable"
]
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"param": {
"type": "string",
"description": "RFC 9535 JSONPath to the offending field."
},
"supported_versions": {
"type": "array",
"items": {
"type": "string"
}
}
}
}AcpCheckoutSessionACP `CheckoutSession` (2026-04-17). `capabilities.payment.handlers` offers `dev.acp.tokenized.card` (psp `stripe`, `merchant_id` = the organizer's connected account) when the organizer can be paid by a Stripe shared payment token; `continue_url` appears whenever a placed order is unpaid.
{
"type": "object",
"description": "ACP `CheckoutSession` (2026-04-17). `capabilities.payment.handlers` offers `dev.acp.tokenized.card` (psp `stripe`, `merchant_id` = the organizer's connected account) when the organizer can be paid by a Stripe shared payment token; `continue_url` appears whenever a placed order is unpaid.",
"required": [
"id",
"status",
"currency",
"line_items",
"totals",
"fulfillment_options",
"messages",
"links",
"capabilities"
],
"additionalProperties": true
}ApiIndex
{
"type": "object",
"required": [
"name",
"version",
"discovery",
"resources"
],
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"description": {
"type": "string"
},
"discovery": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"resources": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"versioning": {
"type": "object",
"additionalProperties": true
}
}
}WebmcpEventSummary
{
"type": "object",
"required": [
"organizer",
"slug",
"name",
"url"
],
"properties": {
"organizer": {
"type": "string"
},
"slug": {
"type": "string"
},
"name": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
},
"startsAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"city": {
"type": [
"string",
"null"
]
},
"venueName": {
"type": [
"string",
"null"
]
},
"fromPrice": {
"type": [
"string",
"null"
]
}
}
}The machine-readable source of this page is /openapi.json. Where this deployment prices an operation, its x-payment-info is added to that document at the edge.