{
  "openapi": "3.1.0",
  "info": {
    "title": "LONG Events Public API",
    "version": "1.3.0",
    "description": "Public REST and MCP entrypoints for event discovery, event weeks, schedules, venues, organizers, artists, concerts by artist, the weekly LONG 5 edition, pricing, and x402 discovery.",
    "x-guidance": "Call GET or POST /api-events with an \"action\" parameter for events, schedules, set times, now playing, and artists, and GET or POST /api-event-weeks with an \"action\" parameter for conference weeks, festivals, cities, tags, and side events. MCP clients can use the streamable HTTP endpoint /mcp-server/mcp instead: initialize, ping, tools/list, and notifications are free; tools/call is metered unless an API key covers it. API requests can use a LONG or Belong key in X-API-Key, and an API-key request can opt into prepaid credit billing with X-Pay-With-Credits. Autonomous agents can call without a key, read the returned HTTP 402 payment requirements, and retry through an advertised x402 lane. The default price is half a cent ($0.005) per call; /api-pricing is authoritative.",
    "termsOfService": "https://long.events/docs",
    "contact": {
      "name": "LONG Events",
      "email": "explore@long.events",
      "url": "https://long.events/docs"
    }
  },
  "externalDocs": {
    "description": "Human-readable API and MCP documentation",
    "url": "https://long.events/docs"
  },
  "servers": [
    {
      "url": "https://long.events/functions/v1",
      "description": "Production"
    }
  ],
  "tags": [
    { "name": "Events and artists", "description": "Event discovery, set times, schedules, artist identity, and concerts by artist." },
    { "name": "Event weeks", "description": "Conference weeks, festivals, cities, tags, and linked side events." },
    { "name": "LONG 5", "description": "Immutable weekly city and headliner chart with verified public profile handles." },
    { "name": "MCP", "description": "Streamable-HTTP Model Context Protocol discovery and tool calls." },
    { "name": "Discovery", "description": "Live pricing and x402 resource metadata." }
  ],
  "paths": {
    "/api-events": {
      "get": {
        "tags": ["Events and artists"],
        "operationId": "getEventsAction",
        "summary": "Run an event, schedule, or artist action",
        "description": "Pass parameters in the query string. `discover` is the default action. Event payloads include catalog `rank` (0-100 from listing completeness), `predicted_end_time` when the listing omitted an end and a later source statement fills it, and `ticket_offer` when a verified price or availability is still fresh. `stats` and `spotlight_candidates` require an API key; all other actions accept any documented access lane. The four artist actions' identity objects carry nullable `mbid` and `spotify_id` anchors; Spotify IDs appear only after cross-provider verification. `catalog_stats` reports catalog size, indexable cities and the busiest cities; `spotlight_candidates` ranks organizers, venues or artists with a public Instagram handle, with 30-day activity windows and the next citable date, and never carries contact fields.",
        "parameters": [
          { "$ref": "#/components/parameters/EventsAction" },
          { "$ref": "#/components/parameters/Latitude" },
          { "$ref": "#/components/parameters/Longitude" },
          { "$ref": "#/components/parameters/City" },
          { "$ref": "#/components/parameters/Country" },
          { "$ref": "#/components/parameters/Category" },
          { "$ref": "#/components/parameters/StartDateCamel" },
          { "$ref": "#/components/parameters/EndDateCamel" },
          { "$ref": "#/components/parameters/StartDateSnake" },
          { "$ref": "#/components/parameters/EndDateSnake" },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" },
          { "$ref": "#/components/parameters/NearLat" },
          { "$ref": "#/components/parameters/NearLng" },
          { "$ref": "#/components/parameters/RadiusKm" },
          { "$ref": "#/components/parameters/SortBy" },
          { "$ref": "#/components/parameters/EditorialPick" },
          { "$ref": "#/components/parameters/EditorialSeries" },
          { "$ref": "#/components/parameters/EventId" },
          { "$ref": "#/components/parameters/EventWeekId" },
          { "$ref": "#/components/parameters/EventWeekSlug" },
          { "$ref": "#/components/parameters/Date" },
          { "$ref": "#/components/parameters/Stage" },
          { "$ref": "#/components/parameters/ArtistName" },
          { "$ref": "#/components/parameters/ArtistId" },
          { "$ref": "#/components/parameters/Slug" },
          { "$ref": "#/components/parameters/Name" },
          { "$ref": "#/components/parameters/Query" },
          { "$ref": "#/components/parameters/Source" },
          { "$ref": "#/components/parameters/MinEvents" },
          { "$ref": "#/components/parameters/UpcomingOnly" },
          { "$ref": "#/components/parameters/SpotlightKind" },
          { "$ref": "#/components/parameters/SpotlightCities" }
        ],
        "security": [
          { "ApiKey": [] },
          { "PaymentSignature": [] },
          { "PaymentSession": [] },
          { "Credits": [] },
          {}
        ],
        "x-payment-info": {
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.005" },
          "protocols": [{ "x402": {} }]
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "post": {
        "tags": ["Events and artists"],
        "operationId": "postEventsAction",
        "summary": "Run an event, schedule, or artist action with a JSON body",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/EventsRequest" },
              "examples": {
                "artistConcerts": {
                  "summary": "Upcoming concerts by artist",
                  "value": {
                    "action": "get_artist_events",
                    "name": "Overmono",
                    "upcoming_only": true,
                    "limit": 20
                  }
                },
                "cityDiscovery": {
                  "summary": "Discover events in a city",
                  "value": {
                    "action": "discover",
                    "city": "Berlin",
                    "category": "electronic",
                    "limit": 20
                  }
                },
                "editorialPicks": {
                  "summary": "Human-approved editorial picks for a city",
                  "value": {
                    "action": "discover",
                    "city": "Berlin",
                    "editorial_pick": true,
                    "limit": 20
                  }
                }
              }
            }
          }
        },
        "security": [
          { "ApiKey": [] },
          { "PaymentSignature": [] },
          { "PaymentSession": [] },
          { "Credits": [] },
          {}
        ],
        "x-payment-info": {
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.005" },
          "protocols": [{ "x402": {} }]
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "options": {
        "tags": ["Events and artists"],
        "operationId": "optionsEvents",
        "summary": "CORS preflight",
        "security": [],
        "responses": { "204": { "description": "CORS headers" } }
      }
    },
    "/long-five": {
      "get": {
        "tags": ["LONG 5"],
        "operationId": "getLongFiveEdition",
        "summary": "Read a public LONG 5 edition",
        "description": "Returns the latest or named immutable five-city by five-headliner edition. The response includes representative events and verified featured artist, venue, and organizer handles; private Spotify scoring evidence is never exposed.",
        "parameters": [
          {
            "name": "edition",
            "in": "query",
            "required": false,
            "description": "`latest` or an ISO-week key such as `2026-W35`.",
            "schema": { "type": "string", "default": "latest", "pattern": "^(latest|[0-9]{4}-W[0-9]{2})$" }
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Immutable LONG 5 edition",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/LongFiveResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api-event-weeks": {
      "get": {
        "tags": ["Event weeks"],
        "operationId": "getEventWeeksAction",
        "summary": "Run an event-week action",
        "description": "Pass parameters in the query string. `list` is the default action.",
        "parameters": [
          { "$ref": "#/components/parameters/EventWeeksAction" },
          { "$ref": "#/components/parameters/Id" },
          { "$ref": "#/components/parameters/Slug" },
          { "$ref": "#/components/parameters/Query" },
          { "$ref": "#/components/parameters/City" },
          { "$ref": "#/components/parameters/Country" },
          { "$ref": "#/components/parameters/Tag" },
          { "$ref": "#/components/parameters/Upcoming" },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "security": [
          { "ApiKey": [] },
          { "PaymentSignature": [] },
          { "PaymentSession": [] },
          { "Credits": [] },
          {}
        ],
        "x-payment-info": {
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.005" },
          "protocols": [{ "x402": {} }]
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "post": {
        "tags": ["Event weeks"],
        "operationId": "postEventWeeksAction",
        "summary": "Run an event-week action with a JSON body",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/EventWeeksRequest" },
              "example": {
                "action": "list",
                "city": "Lisbon",
                "upcoming": true,
                "limit": 20
              }
            }
          }
        },
        "security": [
          { "ApiKey": [] },
          { "PaymentSignature": [] },
          { "PaymentSession": [] },
          { "Credits": [] },
          {}
        ],
        "x-payment-info": {
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.005" },
          "protocols": [{ "x402": {} }]
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      },
      "options": {
        "tags": ["Event weeks"],
        "operationId": "optionsEventWeeks",
        "summary": "CORS preflight",
        "security": [],
        "responses": { "204": { "description": "CORS headers" } }
      }
    },
    "/api-pricing": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getApiPricing",
        "summary": "Get live per-action pricing",
        "description": "No authentication required. Amounts are returned in USD micros, USDC atomic units, LONG wei, self-facilitated BSC stablecoin bundle units, and configured B402 asset units.",
        "security": [],
        "responses": {
          "200": {
            "description": "Current prices and supported payment methods",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SuccessEnvelope" }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/x402-discovery": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getX402Discovery",
        "summary": "Discover every x402-payable API and MCP resource",
        "security": [],
        "responses": {
          "200": {
            "description": "Resource catalog with payment requirements and metadata",
            "content": {
              "application/json": {
                "schema": { "type": "object", "additionalProperties": true }
              }
            }
          },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/mcp-server": {
      "get": {
        "tags": ["MCP"],
        "operationId": "getMcpServerCard",
        "summary": "Get the MCP server card",
        "description": "No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "Machine-readable MCP server metadata",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/McpServerCard" }
              }
            }
          }
        }
      }
    },
    "/mcp-server/mcp": {
      "post": {
        "tags": ["MCP"],
        "operationId": "callMcp",
        "summary": "Send a JSON-RPC request over streamable HTTP",
        "description": "`initialize`, `ping`, `tools/list`, and notifications are free. `tools/call` accepts an API key, credits, an HTTP payment header, or native `_meta[\"x402/payment\"]`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/JsonRpcRequest" },
              "example": {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "tools/call",
                "params": {
                  "name": "search_artists",
                  "arguments": { "artist_name": "Bonobo", "upcoming_only": true }
                }
              }
            }
          }
        },
        "security": [
          { "ApiKey": [] },
          { "PaymentSignature": [] },
          { "PaymentSession": [] },
          { "Credits": [] },
          {}
        ],
        "responses": {
          "200": {
            "description": "JSON-RPC response",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/JsonRpcResponse" }
              }
            }
          },
          "204": { "description": "Notification accepted; notifications have no JSON-RPC response" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "LONG key (`long_...`) or Belong key (`sk_...`)."
      },
      "PaymentSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "PAYMENT-SIGNATURE",
        "description": "Signed x402-v2, self-facilitated BSC stablecoin/LONG tx-hash proof, or B402 payment payload selected from a 402 response. `X-PAYMENT` is accepted as a compatibility alias."
      },
      "PaymentSession": {
        "type": "apiKey",
        "in": "header",
        "name": "X-402-Token",
        "description": "Reusable payment-session token returned after a successful bundled payment."
      },
      "Credits": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Pay-With-Credits",
        "description": "Opt an API-key request into prepaid credit billing."
      }
    },
    "parameters": {
      "EventsAction": {
        "name": "action",
        "in": "query",
        "schema": {
          "type": "string",
          "default": "discover",
          "enum": ["discover", "list", "stats", "catalog_stats", "spotlight_candidates", "get_sets", "get_now_playing", "get_schedule", "search_artists", "get_artist", "get_artist_events", "list_artists"]
        },
        "description": "Action to run."
      },
      "EventWeeksAction": {
        "name": "action",
        "in": "query",
        "schema": {
          "type": "string",
          "default": "list",
          "enum": ["list", "get", "search", "cities", "tags"]
        },
        "description": "Event-week action to run."
      },
      "Latitude": { "name": "latitude", "in": "query", "schema": { "type": "number", "format": "double" }, "description": "Latitude for `discover`; use with longitude." },
      "Longitude": { "name": "longitude", "in": "query", "schema": { "type": "number", "format": "double" }, "description": "Longitude for `discover`; use with latitude." },
      "City": { "name": "city", "in": "query", "schema": { "type": "string" }, "description": "City filter." },
      "Country": { "name": "country", "in": "query", "schema": { "type": "string" }, "description": "Country filter." },
      "Category": { "name": "category", "in": "query", "schema": { "type": "string" }, "description": "Event category filter." },
      "StartDateCamel": { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Start date for event discovery." },
      "EndDateCamel": { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "End date for event discovery." },
      "StartDateSnake": { "name": "start_date", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Start date for artist performances." },
      "EndDateSnake": { "name": "end_date", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "End date for artist performances." },
      "Limit": { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1 }, "description": "Maximum rows to return. Artist actions cap this at 100." },
      "Offset": { "name": "offset", "in": "query", "schema": { "type": "integer", "minimum": 0, "default": 0 }, "description": "Pagination offset." },
      "NearLat": { "name": "near_lat", "in": "query", "schema": { "type": "number", "format": "double" }, "description": "Reference latitude for distance sorting." },
      "NearLng": { "name": "near_lng", "in": "query", "schema": { "type": "number", "format": "double" }, "description": "Reference longitude for distance sorting." },
      "RadiusKm": { "name": "radius_km", "in": "query", "schema": { "type": "number", "minimum": 0 }, "description": "Maximum distance from the reference coordinates, in kilometres." },
      "SortBy": { "name": "sort_by", "in": "query", "schema": { "type": "string", "enum": ["date", "distance"], "default": "date" }, "description": "Event ordering." },
      "EditorialSeries": { "name": "editorial_series", "in": "query", "schema": { "type": "string", "enum": ["long5", "crypto5"] }, "description": "Filter published picks by series. Requires editorial_pick=true. Omit to return both labeled series. LONG5 covers music/culture; CRYPTO5 covers crypto and broader tech." },
      "EditorialPick": { "name": "editorial_pick", "in": "query", "schema": { "type": "boolean", "default": false }, "description": "Only return human-approved editorial picks. Requires city for discover/list." },
      "EventId": { "name": "event_id", "in": "query", "schema": { "type": "string", "format": "uuid" }, "description": "Event UUID for set-time actions." },
      "EventWeekId": { "name": "event_week_id", "in": "query", "schema": { "type": "string", "format": "uuid" }, "description": "Event-week UUID for event and schedule filtering." },
      "EventWeekSlug": { "name": "event_week_slug", "in": "query", "schema": { "type": "string" }, "description": "Event-week slug for event filtering." },
      "Date": { "name": "date", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Schedule date." },
      "Stage": { "name": "stage", "in": "query", "schema": { "type": "string" }, "description": "Schedule stage filter." },
      "ArtistName": { "name": "artist_name", "in": "query", "schema": { "type": "string" }, "description": "Artist query for `search_artists`." },
      "ArtistId": { "name": "artist_id", "in": "query", "schema": { "type": "string", "format": "uuid" }, "description": "Resolve an artist by UUID." },
      "Slug": { "name": "slug", "in": "query", "schema": { "type": "string" }, "description": "Resolve an artist or event week by slug." },
      "Name": { "name": "name", "in": "query", "schema": { "type": "string" }, "description": "Resolve an artist by exact name." },
      "Query": { "name": "query", "in": "query", "schema": { "type": "string" }, "description": "Free-text search query." },
      "Source": { "name": "source", "in": "query", "schema": { "type": "string" }, "description": "Event-source filter for `list_artists`." },
      "MinEvents": { "name": "min_events", "in": "query", "schema": { "type": "integer", "minimum": 0 }, "description": "Minimum tracked performance count." },
      "UpcomingOnly": { "name": "upcoming_only", "in": "query", "schema": { "type": "boolean", "default": true }, "description": "Only future artist performances." },
      "SpotlightKind": { "name": "kind", "in": "query", "schema": { "type": "string", "enum": ["organizer", "venue", "artist"] }, "description": "Subject kind for `spotlight_candidates`." },
      "SpotlightCities": { "name": "cities", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated city filter for `spotlight_candidates` (at most 20; diacritics are folded). Artists match through the city of their next date." },
      "Id": { "name": "id", "in": "query", "schema": { "type": "string", "format": "uuid" }, "description": "Event-week UUID for `get`." },
      "Tag": { "name": "tag", "in": "query", "schema": { "type": "string" }, "description": "Event-week tag filter." },
      "Upcoming": { "name": "upcoming", "in": "query", "schema": { "type": "boolean", "default": true }, "description": "Exclude past event weeks when true." }
    },
    "headers": {
      "RateLimit": { "description": "Maximum requests per minute for this access lane.", "schema": { "type": "integer" } },
      "RateRemaining": { "description": "Requests remaining in the current minute.", "schema": { "type": "integer" } },
      "RateReset": { "description": "Rate-limit reset time. REST endpoints return an ISO timestamp; MCP returns Unix seconds.", "schema": { "type": ["string", "integer"] } },
      "PaymentRequired": { "description": "Base64-encoded x402-v2 requirements. `X-PAYMENT-REQUIREMENTS` is a compatibility alias.", "schema": { "type": "string" } },
      "PaymentResponse": { "description": "Base64-encoded settlement receipt.", "schema": { "type": "string" } },
      "PaymentToken": { "description": "Reusable bundled-payment session token.", "schema": { "type": "string" } },
      "CallsRemaining": { "description": "Calls remaining in the bundled-payment session.", "schema": { "type": "integer" } }
    },
    "responses": {
      "Success": {
        "description": "Successful action. The `data` shape depends on the selected action.",
        "headers": {
          "X-RateLimit-Limit": { "$ref": "#/components/headers/RateLimit" },
          "X-RateLimit-Remaining": { "$ref": "#/components/headers/RateRemaining" },
          "X-RateLimit-Reset": { "$ref": "#/components/headers/RateReset" },
          "PAYMENT-RESPONSE": { "$ref": "#/components/headers/PaymentResponse" },
          "X-402-Token": { "$ref": "#/components/headers/PaymentToken" },
          "X-Calls-Remaining": { "$ref": "#/components/headers/CallsRemaining" }
        },
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/SuccessEnvelope" }
          }
        }
      },
      "BadRequest": { "$ref": "#/components/responses/Error400" },
      "Unauthorized": { "$ref": "#/components/responses/Error401" },
      "PaymentRequired": {
        "description": "No valid access lane was supplied. Select an accepted payment requirement and retry the same request.",
        "headers": {
          "PAYMENT-REQUIRED": { "$ref": "#/components/headers/PaymentRequired" },
          "X-PAYMENT-REQUIREMENTS": { "$ref": "#/components/headers/PaymentRequired" }
        },
        "content": {
          "application/json": {
            "schema": { "type": "object", "additionalProperties": true }
          }
        }
      },
      "NotFound": { "$ref": "#/components/responses/Error404" },
      "RateLimited": { "$ref": "#/components/responses/Error429" },
      "ServerError": { "$ref": "#/components/responses/Error500" },
      "Error400": { "description": "Invalid action or parameters.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } } },
      "Error401": { "description": "Invalid or expired credentials.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } } },
      "Error404": { "description": "Requested event, artist, or event week was not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } } },
      "Error429": { "description": "Rate limit exceeded.", "headers": { "X-RateLimit-Reset": { "$ref": "#/components/headers/RateReset" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } } },
      "Error500": { "description": "Unexpected server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } } }
    },
    "schemas": {
      "EventsRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "action": { "$ref": "#/components/parameters/EventsAction/schema" },
          "latitude": { "type": "number" },
          "longitude": { "type": "number" },
          "city": { "type": "string" },
          "country": { "type": "string" },
          "category": { "type": "string" },
          "startDate": { "type": "string", "format": "date" },
          "endDate": { "type": "string", "format": "date" },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date" },
          "limit": { "type": "integer", "minimum": 1 },
          "offset": { "type": "integer", "minimum": 0 },
          "near_lat": { "type": "number" },
          "near_lng": { "type": "number" },
          "radius_km": { "type": "number", "minimum": 0 },
          "sort_by": { "type": "string", "enum": ["date", "distance"] },
          "editorial_pick": { "type": "boolean", "default": false },
          "editorial_series": { "type": "string", "enum": ["long5", "crypto5"], "description": "Requires editorial_pick=true. Omit to return both labeled series." },
          "event_id": { "type": "string", "format": "uuid" },
          "event_week_id": { "type": "string", "format": "uuid" },
          "event_week_slug": { "type": "string" },
          "date": { "type": "string", "format": "date" },
          "stage": { "type": "string" },
          "artist_name": { "type": "string" },
          "artist_id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "query": { "type": "string" },
          "source": { "type": "string" },
          "min_events": { "type": "integer", "minimum": 0 },
          "upcoming_only": { "type": "boolean", "default": true },
          "kind": { "type": "string", "enum": ["organizer", "venue", "artist"] },
          "cities": { "type": "array", "items": { "type": "string" }, "maxItems": 20 }
        }
      },
      "EventWeeksRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "action": { "$ref": "#/components/parameters/EventWeeksAction/schema" },
          "id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "query": { "type": "string" },
          "q": { "type": "string", "description": "Alias for query." },
          "city": { "type": "string" },
          "country": { "type": "string" },
          "tag": { "type": "string" },
          "upcoming": { "type": "boolean", "default": true },
          "limit": { "type": "integer", "minimum": 1 },
          "offset": { "type": "integer", "minimum": 0 }
        }
      },
      "LongFiveResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["success", "edition_key", "generated_at", "payload_sha256", "payload"],
        "properties": {
          "success": { "const": true },
          "edition_key": { "type": "string", "pattern": "^[0-9]{4}-W[0-9]{2}$" },
          "generated_at": { "type": "string", "format": "date-time" },
          "payload_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
          "payload": {
            "type": "object",
            "required": ["schema_version", "edition_key", "rankings", "instagram_coverage", "landing_url"],
            "additionalProperties": true
          }
        }
      },
      "ArtistIdentity": {
        "type": "object",
        "additionalProperties": true,
        "required": ["id", "slug", "name", "mbid", "spotify_id"],
        "properties": {
          "id": { "type": "string", "format": "uuid", "description": "LONG Events artist UUID." },
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "mbid": {
            "type": ["string", "null"],
            "format": "uuid",
            "description": "Accepted MusicBrainz artist ID, or null when no unambiguous mapping is available."
          },
          "spotify_id": {
            "type": ["string", "null"],
            "pattern": "^[A-Za-z0-9]{22}$",
            "description": "Spotify artist ID backed by cross-provider verification, or null. Name-only listener-library matches are never published."
          }
        }
      },
      "SuccessEnvelope": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": { "const": true },
          "data": {
            "type": "object",
            "description": "Action-specific result. Artist actions use ArtistIdentity for `artist` and each member of `artists`.",
            "properties": {
              "events": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "editorial_pick": { "type": "boolean", "description": "Present on human-approved editorial results." },
                    "editorial_series": { "type": "string", "enum": ["long5", "crypto5"], "description": "Published editorial series; LONG5 is culture/music, CRYPTO5 is crypto and broader tech." },
                    "editorial_blurb": { "type": "string", "description": "Approved reader-facing copy." },
                    "editorial_is_city_pick": { "type": "boolean", "description": "Lead event in its published round." }
                  },
                  "additionalProperties": true
                }
              },
              "artist": { "$ref": "#/components/schemas/ArtistIdentity" },
              "artists": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/ArtistIdentity" }
              }
            },
            "additionalProperties": true
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": ["success", "error"],
        "properties": {
          "success": { "const": false },
          "error": { "type": "string" }
        }
      },
      "McpServerCard": {
        "type": "object",
        "required": ["status", "name", "version", "mcp_endpoint", "transport", "tools_count", "free_methods"],
        "properties": {
          "status": { "const": "ok" },
          "name": { "type": "string" },
          "version": { "type": "string" },
          "description": { "type": "string" },
          "mcp_endpoint": { "type": "string" },
          "transport": { "const": "streamable-http" },
          "tools_count": { "type": "integer" },
          "free_methods": { "type": "array", "items": { "type": "string" } },
          "authentication": { "type": "array", "items": { "type": "string" } },
          "payments": { "type": "object", "additionalProperties": true }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "required": ["jsonrpc", "method"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": { "type": ["string", "number", "null"] },
          "method": { "type": "string", "enum": ["initialize", "ping", "tools/list", "tools/call", "notifications/initialized"] },
          "params": { "type": "object", "additionalProperties": true }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "required": ["jsonrpc"],
        "properties": {
          "jsonrpc": { "const": "2.0" },
          "id": { "type": ["string", "number", "null"] },
          "result": { "type": "object", "additionalProperties": true },
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "integer" },
              "message": { "type": "string" },
              "data": {}
            }
          }
        }
      }
    }
  }
}
