openapi: "3.0.3" info: title: Zentix Ticket Agent API description: | Public API for AI agents to discover events, check ticket availability, and generate checkout links. Agents never handle payment. Purchase flow (follow these steps in order): 1. GET /events — browse all events 2. GET /events/{id}/dates — see available dates with price ranges 3. GET /events/{id}/ticket-types?date= — see ticket options for a date 4. GET /events/{id}/sessions?date= — see time slots with per-ticket pricing 5. GET /checkout-link — ALWAYS use this to get a checkout URL. Never construct checkout URLs yourself. IMPORTANT: Inventory is NOT held until the user clicks the checkout link and begins checkout. Tell the user to act quickly if availability is limited. version: "1.0.0" contact: email: support@zentix.com servers: - url: https://api.zentix.com/api/agent description: Zentix agent API paths: /events: get: operationId: listEvents summary: "Step 1: List all published events" responses: "200": description: List of events content: application/json: schema: type: object properties: events: type: array items: type: object properties: id: { type: string, format: uuid } name: { type: string } description: { type: string, nullable: true } venue: type: object properties: name: { type: string } address: { type: string } city: { type: string } state: { type: string } timezone: { type: string } start_date: { type: string, format: date } end_date: { type: string, format: date, nullable: true } price_range: type: object nullable: true properties: min: { type: number } max: { type: number } currency: { type: string } status: { type: string, enum: [on_sale, sold_out] } event_url: { type: string, format: uri } image_url: { type: string, format: uri, nullable: true } /events/{eventId}/dates: get: operationId: getEventDates summary: "Step 2: Available dates for an event" description: Returns future dates with availability status and price range. parameters: - name: eventId in: path required: true schema: { type: string, format: uuid } responses: "200": description: Available dates content: application/json: schema: type: object properties: event_id: { type: string } event_name: { type: string } dates: type: array items: type: object properties: date: { type: string, format: date } day_of_week: { type: string } availability: { type: string, enum: [available, limited, sold_out] } price_range: type: object nullable: true properties: min: { type: number } max: { type: number } currency: { type: string } sessions_available: { type: integer } /events/{eventId}/ticket-types: get: operationId: getTicketTypes summary: "Step 3: Ticket types for a specific date" description: Returns ticket type options with starting prices for the selected date. parameters: - name: eventId in: path required: true schema: { type: string, format: uuid } - name: date in: query required: true schema: { type: string, format: date } responses: "200": description: Ticket types for date content: application/json: schema: type: object properties: event_id: { type: string } event_name: { type: string } date: { type: string, format: date } ticket_types: type: array items: type: object properties: id: { type: string, format: uuid } name: { type: string } price_from: { type: number } currency: { type: string } availability: { type: string, enum: [available, limited, sold_out] } /events/{eventId}/sessions: get: operationId: getEventSessions summary: "Step 4: Time slots with per-ticket pricing and fees" description: Returns sessions for a date with per-ticket-type pricing including fees. parameters: - name: eventId in: path required: true schema: { type: string, format: uuid } - name: date in: query required: true schema: { type: string, format: date } responses: "200": description: Sessions with ticket pricing content: application/json: schema: type: object properties: event_id: { type: string } event_name: { type: string } date: { type: string, format: date } timezone: { type: string } sessions: type: array items: type: object properties: id: { type: string, format: uuid } start_time: { type: string, format: date-time } end_time: { type: string, format: date-time } label: { type: string, nullable: true } local_time: { type: string, nullable: true } ticket_types: type: array items: type: object properties: id: { type: string, format: uuid } name: { type: string } price: { type: number } fees: { type: number } total: { type: number, description: "All-in per-ticket" } currency: { type: string } availability: { type: string, enum: [available, limited, sold_out] } /checkout-link: get: operationId: getCheckoutLink summary: "Step 5: Generate a checkout link — ALWAYS use this, never construct URLs yourself" description: | IMPORTANT: Always call this endpoint to get a checkout URL. Do NOT construct checkout URLs yourself — they require a special format. Accepts UUIDs (sessionId + items) or human-readable params (date + time + ticketType + quantity). Inventory is NOT held until the user clicks the link and starts checkout. parameters: - name: eventId in: query required: true schema: { type: string, format: uuid } - name: sessionId in: query required: false schema: { type: string, format: uuid } description: "Session UUID from /sessions response. Or use date+time instead." - name: items in: query required: false schema: { type: string } description: "ticketTypeId:quantity pairs. Or use ticketType+quantity instead." - name: date in: query required: false schema: { type: string, format: date } description: "Alternative to sessionId: date in YYYY-MM-DD" - name: time in: query required: false schema: { type: string } description: "Alternative to sessionId: time like 7:00 PM or 19:00" - name: ticketType in: query required: false schema: { type: string } description: "Alternative to items: ticket type name (e.g. general_admission)" - name: quantity in: query required: false schema: { type: integer } description: "Alternative to items: number of tickets (default 1)" responses: "200": description: Checkout URL with order summary content: application/json: schema: type: object properties: checkout_url: { type: string, format: uri } summary: type: object properties: event_name: { type: string } session_date: { type: string, format: date } session_time: { type: string, format: date-time } line_items: type: array items: type: object properties: ticket_type_name: { type: string } quantity: { type: integer } unit_price: { type: number } fees: { type: number } estimated_total: { type: number } currency: { type: string } /notify-signup: post: operationId: notifySignup summary: Sign up for on-sale reminders requestBody: required: true content: application/json: schema: type: object required: [email, event_id] properties: email: { type: string, format: email } event_id: { type: string, format: uuid } responses: "201": description: Signup confirmed "409": description: Already signed up