{
  "openapi": "3.1.0",
  "info": {
    "title": "Ticket-alerts.live API",
    "version": "1.0.0",
    "summary": "Search the events Ticket-alerts.live monitors for face-value resale tickets.",
    "description": "Public, read-only JSON API for Ticket-alerts.live, which watches official resale platforms (Twickets, the official Wimbledon resale and similar) for sold-out events and alerts subscribers the moment a face-value ticket is listed. No API key is needed.\n\nErrors are RFC 9457 problem details (`application/problem+json`) with a machine-readable `code` and a `hint` describing how to fix the request.\n\nAI agents can also use the MCP server at https://ticket-alerts.live/mcp (Streamable HTTP), which adds upcoming-event listings, full event details with sign-up links, and pricing. Sign-up itself happens on each event page.",
    "termsOfService": "https://ticket-alerts.live/terms",
    "contact": {
      "name": "Ticket-alerts.live support",
      "url": "https://ticket-alerts.live/contact",
      "email": "support@ticket-alerts.live"
    }
  },
  "externalDocs": {
    "description": "Developer docs",
    "url": "https://ticket-alerts.live/developers"
  },
  "servers": [
    {
      "url": "https://ticket-alerts.live"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Search",
      "description": "Find tracked events and the artist, festival and team pages that group them."
    }
  ],
  "paths": {
    "/api/search.json": {
      "get": {
        "operationId": "search",
        "tags": [
          "Search"
        ],
        "summary": "Search tracked events and artists",
        "description": "Case-insensitive match on event, artist, festival, team, venue and city names, across past and upcoming events. Returns up to 6 `subject` hits (artist, festival or team pages at `/alerts/{slug}`) followed by up to 12 `event` hits (`/event/{slug}`); the result set is not paginated. Queries shorter than 2 characters return no hits. Responses are cached for 60 seconds.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search text, 2–100 characters after trimming. Shorter queries return an empty `hits` array.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "oasis"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching subjects and events.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                },
                "example": {
                  "q": "oasis",
                  "hits": [
                    {
                      "type": "subject",
                      "slug": "oasis",
                      "name": "Oasis",
                      "kind": "artist",
                      "thumbnail_url": "https://images.ticket-alerts.live/cdn-cgi/image/format=auto,quality=82,fit=cover,onerror=redirect,width=96/https://images.ticket-alerts.live/cms/68e95fd3423c2473c0339ab5_oasis-1828444849901146112.webp"
                    },
                    {
                      "type": "event",
                      "slug": "oasis-london-july-aug-2025",
                      "name": "Oasis London Jul/Aug 2025",
                      "venue": "Wembley Stadium",
                      "city": "London",
                      "dates": "July 25, 26, 30 & August 2, 3, 2025",
                      "thumbnail_url": "https://images.ticket-alerts.live/cdn-cgi/image/format=auto,quality=82,fit=cover,onerror=redirect,width=96/https://images.ticket-alerts.live/cms/687cf2d7f6de3ecf85115156_Oasis%20Reunion%20Tour%20Concert-opt.webp"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`q` is longer than 100 characters (`query_too_long`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://ticket-alerts.live/developers#error-query_too_long",
                  "title": "Query too long",
                  "status": 400,
                  "detail": "q is 140 characters; the maximum is 100.",
                  "instance": "/api/search.json?q=…",
                  "code": "query_too_long",
                  "hint": "Shorten q to 100 characters or fewer: an artist, event, festival, team, venue or city name."
                }
              }
            }
          },
          "405": {
            "description": "Method other than GET or HEAD (`method_not_allowed`).",
            "headers": {
              "Allow": {
                "description": "Supported methods.",
                "schema": {
                  "type": "string",
                  "example": "GET, HEAD"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://ticket-alerts.live/developers#error-method_not_allowed",
                  "title": "Method not allowed",
                  "status": 405,
                  "detail": "POST is not supported on /api/search.json.",
                  "instance": "/api/search.json?q=…",
                  "code": "method_not_allowed",
                  "hint": "The API is read-only: use GET (or HEAD)."
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`internal_error`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://ticket-alerts.live/developers#error-internal_error",
                  "title": "Internal server error",
                  "status": 500,
                  "detail": "The server failed to handle GET /api/search.json.",
                  "instance": "/api/search.json?q=…",
                  "code": "internal_error",
                  "hint": "Retry after a few seconds. If it keeps failing, email support@ticket-alerts.live with the request URL."
                }
              }
            }
          },
          "503": {
            "description": "The event catalog could not be queried (`search_unavailable`).",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "example": 5
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://ticket-alerts.live/developers#error-search_unavailable",
                  "title": "Search temporarily unavailable",
                  "status": 503,
                  "detail": "The event catalog could not be queried.",
                  "instance": "/api/search.json?q=…",
                  "code": "search_unavailable",
                  "hint": "The event catalog could not be reached. Retry after the number of seconds in Retry-After."
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SearchResponse": {
        "type": "object",
        "required": [
          "q",
          "hits"
        ],
        "additionalProperties": false,
        "properties": {
          "q": {
            "type": "string",
            "description": "The trimmed query."
          },
          "hits": {
            "type": "array",
            "description": "Subject hits first, then event hits.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/SubjectHit"
                },
                {
                  "$ref": "#/components/schemas/EventHit"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "subject": "#/components/schemas/SubjectHit",
                  "event": "#/components/schemas/EventHit"
                }
              }
            }
          }
        }
      },
      "SubjectHit": {
        "type": "object",
        "description": "An artist, festival, team or production. Its page is https://ticket-alerts.live/alerts/{slug}.",
        "required": [
          "type",
          "slug",
          "name",
          "kind",
          "thumbnail_url"
        ],
        "additionalProperties": false,
        "properties": {
          "type": {
            "const": "subject"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "description": "artist, festival, team, tournament, production, comedian, classical or other."
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL of a 96 px wide thumbnail."
          }
        }
      },
      "EventHit": {
        "type": "object",
        "description": "One tracked event. Its page, where users sign up for alerts, is https://ticket-alerts.live/event/{slug}.",
        "required": [
          "type",
          "slug",
          "name",
          "venue",
          "city",
          "dates",
          "thumbnail_url"
        ],
        "additionalProperties": false,
        "properties": {
          "type": {
            "const": "event"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "venue": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "dates": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable date range, e.g. \"June 29 - July 12, 2026\"."
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL of a 96 px wide thumbnail."
          }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details, with `code` and `hint` extension members.",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code",
          "hint"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "Documentation URI for this problem type."
          },
          "title": {
            "type": "string",
            "description": "Short summary of the problem type."
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599,
            "description": "HTTP status code."
          },
          "detail": {
            "type": "string",
            "description": "What went wrong with this request."
          },
          "instance": {
            "type": "string",
            "description": "Path and query of the failed request."
          },
          "code": {
            "type": "string",
            "enum": [
              "bad_request",
              "query_too_long",
              "not_found",
              "method_not_allowed",
              "internal_error",
              "search_unavailable"
            ],
            "description": "Stable, machine-readable error code."
          },
          "hint": {
            "type": "string",
            "description": "How to fix or retry the request."
          }
        }
      }
    }
  }
}