{"openapi":"3.1.0","info":{"title":"CaptainTicket API","version":"1.0.0","description":"Read-only access to a ticket shop's public data: events with live availability, ticket shop URLs and active payment methods. Authenticate with an API token (Dashboard → Instellingen → API-tokens) as `Authorization: Bearer ctk_…`. All timestamps are ISO 8601; event times are Europe/Amsterdam. Money is integer cents. A `null` capacity or availability means unlimited."},"servers":[{"url":"https://next.captainticket.nl"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"ctk_"}}},"security":[{"bearerAuth":[]}],"paths":{"/api/v1/shop":{"get":{"summary":"Get the shop","description":"The shop's public identity: name, slug, enabled locales and the absolute ticketshop URL per locale. `testMode` is true while the platform admin has the shop in Pay.nl test mode — surface it so buyers are never confused.","operationId":"getShop","security":[{"bearerAuth":[]}],"tags":["Shop"],"responses":{"200":{"description":"The shop.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"urls":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"locales":{"type":"array","items":{"type":"string"}},"testMode":{"type":"boolean"}},"required":["id","slug","name","urls","locales","testMode"],"additionalProperties":false}}}},"401":{"description":"Missing, invalid, expired or revoked token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded (600 requests per token per hour).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}}}},"/api/v1/events":{"get":{"summary":"List events","description":"The shop's public events (visible, not archived, not a concept) with a live sold-out flag per event. Events start with the earliest `startsAt`; events without one sort last. Page with `limit`/`offset`.","operationId":"listEvents","security":[{"bearerAuth":[]}],"tags":["Events"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Page size (1–100, default 50)."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0},"description":"Page offset (default 0)."}],"responses":{"200":{"description":"The shop's events.","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":"string"},"startsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"endsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"onSale":{"type":"boolean"},"soldOut":{"type":"boolean"},"url":{"type":"string"},"location":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"address":{"type":["string","null"]}},"required":["name","address"],"additionalProperties":false},{"type":"null"}]}},"required":["id","name","startsAt","endsAt","onSale","soldOut","url","location"],"additionalProperties":false}},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"offset":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["events","total","limit","offset"],"additionalProperties":false}}}},"400":{"description":"Malformed query parameters.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"401":{"description":"Missing, invalid, expired or revoked token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded (600 requests per token per hour).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}}}},"/api/v1/events/{eventId}":{"get":{"summary":"Get an event","description":"One event's full public payload: description, sale window, location, per-tier prices and live availability, time slots, and the public URL per locale. An event that is missing, archived, invisible, a concept, or another shop's answers 404 exactly like a nonexistent id.","operationId":"getEvent","security":[{"bearerAuth":[]}],"tags":["Events"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","minimum":1},"description":"The event id, as returned by the list endpoint."}],"responses":{"200":{"description":"The event.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":"string"},"startsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"endsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"onSale":{"type":"boolean"},"soldOut":{"type":"boolean"},"url":{"type":"string"},"location":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]}},"required":["name","address","latitude","longitude"],"additionalProperties":false},{"type":"null"}]},"description":{"type":"string"},"saleStartsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"coverImageUrl":{"type":["string","null"]},"presale":{"type":"object","properties":{"enabled":{"type":"boolean"},"startsAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["enabled","startsAt"],"additionalProperties":false},"queue":{"type":"boolean"},"urls":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"tiers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":"string"},"description":{"type":["string","null"]},"priceCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"vatRate":{"type":"string","enum":["free","zero","low","high"]},"capacity":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"available":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"soldOut":{"type":"boolean"},"onSale":{"type":"boolean"},"minimumOrderCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"maximumOrderCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"increment":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"timeSlots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":["string","null"]},"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["id","name","start","end"],"additionalProperties":false}}},"required":["id","name","description","priceCents","vatRate","capacity","available","soldOut","onSale","minimumOrderCount","maximumOrderCount","increment","timeSlots"],"additionalProperties":false}},"timeSlots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":["string","null"]},"start":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"end":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["id","name","start","end"],"additionalProperties":false}}},"required":["id","name","startsAt","endsAt","onSale","soldOut","url","location","description","saleStartsAt","coverImageUrl","presale","queue","urls","tiers","timeSlots"],"additionalProperties":false}}}},"401":{"description":"Missing, invalid, expired or revoked token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"No such event in this shop.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded (600 requests per token per hour).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}}}},"/api/v1/payment-methods":{"get":{"summary":"List active payment methods","description":"The shop's configured payment methods (its allowlist intersected with the platform-enabled set; no selection means iDEAL only). Read from the local reference tables — no provider call is made. The exact set a buyer may pick is re-resolved against Pay.nl at checkout, so treat this as configuration, not a checkout guarantee.","operationId":"listPaymentMethods","security":[{"bearerAuth":[]}],"tags":["Payment methods"],"responses":{"200":{"description":"The shop's payment methods.","content":{"application/json":{"schema":{"type":"object","properties":{"methods":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":"string"},"type":{"type":"string","enum":["standard","voucher"]}},"required":["id","name","type"],"additionalProperties":false}}},"required":["methods"],"additionalProperties":false}}}},"401":{"description":"Missing, invalid, expired or revoked token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded (600 requests per token per hour).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_request","unauthorized","not_found","rate_limited"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}}}}}}