{
  "openapi": "3.1.0",
  "info": {
    "title": "Event Escapes API",
    "version": "1.0.0",
    "description": "Search and book event trips (tickets, hotels near the venue, curated packages, experiences) with Event Escapes. Built for AI agents and partners. Search is open. Booking returns a secure payment link that the customer pays; nothing is charged by the API. Bookings require acceptance of the AI Agent Terms (https://eventescapes.com/terms/ai-agents). The same capabilities are available over MCP at https://mcp.eventescapes.com/sse.",
    "termsOfService": "https://eventescapes.com/terms/ai-agents",
    "contact": {
      "name": "Event Escapes support",
      "email": "support@eventescapes.com",
      "url": "https://eventescapes.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://eventescapes.com"
    }
  ],
  "security": [],
  "paths": {
    "/api/v1/events": {
      "get": {
        "operationId": "searchEvents",
        "summary": "Search upcoming sports and music events",
        "description": "Event inventory (tickets only) with prices and page links. Prices are estimates; the final price is set at checkout.",
        "parameters": [
          {
            "name": "sport",
            "in": "query",
            "required": false,
            "description": "Sport or category.",
            "schema": {
              "type": "string",
              "enum": [
                "f1",
                "motogp",
                "soccer",
                "premier_league",
                "la_liga",
                "champions_league",
                "nfl",
                "nhl",
                "mlb",
                "nba",
                "tennis",
                "rugby",
                "volleyball",
                "golf",
                "cricket",
                "boxing",
                "mma",
                "horse_racing",
                "athletics",
                "music"
              ]
            }
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "City name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "ISO country code, e.g. US.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2}$"
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Earliest event date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Latest event date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for prices.",
            "schema": {
              "type": "string",
              "enum": [
                "AUD",
                "USD",
                "NZD",
                "GBP",
                "EUR",
                "SGD",
                "CAD",
                "MYR"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum results.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events: { events: [...], count, currency, message }",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequestFailed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Upstream"
          }
        }
      }
    },
    "/api/v1/events/{idOrSlug}": {
      "get": {
        "operationId": "getEventDetails",
        "summary": "Full details for one event",
        "parameters": [
          {
            "name": "idOrSlug",
            "in": "path",
            "required": true,
            "description": "Event UUID (event_id) or slug from /api/v1/events.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for prices.",
            "schema": {
              "type": "string",
              "enum": [
                "AUD",
                "USD",
                "NZD",
                "GBP",
                "EUR",
                "SGD",
                "CAD",
                "MYR"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ event: {...}, message }",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequestFailed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Upstream"
          }
        }
      }
    },
    "/api/v1/events/{idOrSlug}/hotels": {
      "get": {
        "operationId": "searchHotelsNearEvent",
        "summary": "Hotels within walking or short transit distance of the venue",
        "description": "Live prices, never cached. Without dates, defaults to the night before through the night after the event.",
        "parameters": [
          {
            "name": "idOrSlug",
            "in": "path",
            "required": true,
            "description": "Event UUID (event_id) or slug from /api/v1/events.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "check_in",
            "in": "query",
            "required": false,
            "description": "Check-in date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "check_out",
            "in": "query",
            "required": false,
            "description": "Check-out date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "guests",
            "in": "query",
            "required": false,
            "description": "Guests.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 6,
              "default": 2
            }
          },
          {
            "name": "radius_km",
            "in": "query",
            "required": false,
            "description": "Search radius around the venue.",
            "schema": {
              "type": "number",
              "minimum": 0.5,
              "maximum": 10,
              "default": 3
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for prices.",
            "schema": {
              "type": "string",
              "enum": [
                "AUD",
                "USD",
                "NZD",
                "GBP",
                "EUR",
                "SGD",
                "CAD",
                "MYR"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum results.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 15,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ hotels: [{ hotel_id, name, price_per_night, total_price, currency, distance_km, transport_mode, transport_time, ... }], message }",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequestFailed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Upstream"
          }
        }
      }
    },
    "/api/v1/packages": {
      "get": {
        "operationId": "searchPackages",
        "summary": "Curated trip packages (event + hotel + experiences)",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Package category.",
            "schema": {
              "type": "string",
              "enum": [
                "concerts",
                "f1",
                "motogp",
                "world_cup",
                "tennis",
                "nfl",
                "mlb",
                "nba",
                "nhl",
                "epl",
                "la_liga",
                "serie_a",
                "bundesliga",
                "ucl",
                "mls",
                "ligue_1",
                "city_multi",
                "festivals"
              ]
            }
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "Destination city.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Destination country name, e.g. USA.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "package_type",
            "in": "query",
            "required": false,
            "description": "Package type.",
            "schema": {
              "type": "string",
              "enum": [
                "single_event",
                "multi_event_city"
              ]
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Earliest date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Latest date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for prices.",
            "schema": {
              "type": "string",
              "enum": [
                "AUD",
                "USD",
                "NZD",
                "GBP",
                "EUR",
                "SGD",
                "CAD",
                "MYR"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum results.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 15,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ packages: [...], count, currency, message }",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequestFailed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Upstream"
          }
        }
      }
    },
    "/api/v1/experiences": {
      "get": {
        "operationId": "searchExperiences",
        "summary": "Tours, attractions, food and nightlife in a city",
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "required": true,
            "description": "City name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "ISO country code.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2}$"
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Start date (default today).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "End date (default 7 days).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Category.",
            "schema": {
              "type": "string",
              "enum": [
                "tours",
                "attractions",
                "food",
                "sports",
                "transfers",
                "nightlife"
              ]
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for prices.",
            "schema": {
              "type": "string",
              "enum": [
                "AUD",
                "USD",
                "NZD",
                "GBP",
                "EUR",
                "SGD",
                "CAD",
                "MYR"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum results.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 15,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ activities: [...], message }",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequestFailed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Upstream"
          }
        }
      }
    },
    "/api/v1/payment-links": {
      "post": {
        "operationId": "createPaymentLink",
        "summary": "Book for a customer: lock live prices and get a secure payment link",
        "description": "Creates a booking cart and returns a payment URL the customer pays. Requires agent_terms_accepted: true (AI Agent Terms) and the customer's own words asking for the booking. Totals above about AUD 5,000 also need total_confirmation in the customer's words; above about AUD 20,000 the customer books with our team. A result with status action_required lists what is still needed; call again with the same items plus those fields. Every payment link is recorded with the agent, consent, items and total as booking evidence.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentLinkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ status: 'payment_link_ready' | 'action_required', payment_url?, expires_in_minutes?, authorisation_id?, agent_terms_version?, steps, message }",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequestFailed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Upstream"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PaymentLinkRequest": {
        "type": "object",
        "required": [
          "customer_email",
          "customer_first_name",
          "customer_last_name",
          "customer_consent",
          "items",
          "agent_terms_accepted"
        ],
        "properties": {
          "customer_email": {
            "type": "string",
            "format": "email"
          },
          "customer_first_name": {
            "type": "string",
            "maxLength": 80
          },
          "customer_last_name": {
            "type": "string",
            "maxLength": 80
          },
          "customer_phone": {
            "type": "string",
            "maxLength": 20,
            "description": "E.164, if known."
          },
          "residency_country": {
            "type": "string",
            "maxLength": 60,
            "description": "Customer's country of residence, if stated (hotel prices vary by residency)."
          },
          "customer_consent": {
            "type": "string",
            "minLength": 2,
            "maxLength": 500,
            "description": "The customer's own words asking to book these items."
          },
          "agent_terms_accepted": {
            "type": "boolean",
            "const": true,
            "description": "Acceptance of https://eventescapes.com/terms/ai-agents."
          },
          "agent_name": {
            "type": "string",
            "maxLength": 80,
            "description": "Name of the AI assistant making the booking."
          },
          "total_confirmation": {
            "type": "string",
            "maxLength": 300,
            "description": "Only when a previous result asked for it: the customer's words confirming the total."
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 4,
            "items": {
              "$ref": "#/components/schemas/BookingItem"
            }
          },
          "attendee_names": {
            "type": "string",
            "maxLength": 600
          },
          "attendee_details": {
            "type": "string",
            "maxLength": 2000
          },
          "details_confirm_quote": {
            "type": "string",
            "maxLength": 500
          },
          "accept_new_price": {
            "type": "boolean"
          },
          "promo_code": {
            "type": "string",
            "maxLength": 40
          }
        }
      },
      "BookingItem": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "hotel",
              "event",
              "experience"
            ]
          },
          "hotel_id": {
            "type": "string",
            "description": "HOTEL: from /api/v1/events/{idOrSlug}/hotels."
          },
          "check_in": {
            "type": "string",
            "format": "date"
          },
          "check_out": {
            "type": "string",
            "format": "date"
          },
          "adults": {
            "type": "integer",
            "minimum": 1,
            "maximum": 6
          },
          "children": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6
          },
          "breakfast": {
            "type": "boolean"
          },
          "free_cancellation": {
            "type": "boolean"
          },
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "EVENT: from /api/v1/events."
          },
          "event_slug": {
            "type": "string"
          },
          "ticket_id": {
            "type": "string"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10
          },
          "activity_code": {
            "type": "string",
            "description": "EXPERIENCE: from /api/v1/experiences."
          },
          "activity_date": {
            "type": "string",
            "format": "date"
          },
          "child_ages": {
            "type": "string"
          },
          "modality_code": {
            "type": "string"
          },
          "session_code": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "RequestFailed": {
        "description": "The request could not be completed; message says what to fix.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests; see Retry-After.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Upstream": {
        "description": "Temporary upstream problem; retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}