diff --git a/src/_generated/schema.ts b/src/_generated/schema.ts index 7e47e6e..3541097 100644 --- a/src/_generated/schema.ts +++ b/src/_generated/schema.ts @@ -12,8 +12,8 @@ export interface paths { cookie?: never; }; /** - * GET /v1/destinations - * @description Every destination we hold, each with its parks as id and name. This is the entry point: take a destination or park id from here and ask GET /v1/entity/{id}/children for what is inside it, /live for what it is doing, or /schedule for when it is open. Soft-deleted parks are excluded. The list is small and changes when a resort opens or closes a park, which is rarely — cached `public, max-age=300, s-maxage=3600`, and there is no reason to ask for it more than once a run. + * List destinations + * @description Returns every destination with its parks (id and name). This is the place to start: take an id from here and call GET /v1/entity/{id}/children for what is inside it, /live for what it is doing, or /schedule for its opening hours. Cache it; it rarely changes. */ get: operations["getAllDestinations"]; put?: never; @@ -32,8 +32,8 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id} - * @description The entity document: what this thing IS, not what it is doing. Name, entityType, timezone, location, its place in the destination/park hierarchy, and the ride's own attributes. `id` is an entity's UUID, its slug, or — for a destination only — its upstream external id. An id that resolves to nothing is 404, including one malformed enough that the query itself rejects it. Attributes recorded as tags are spread into the document as top-level keys named after the tag — `minimumHeight`, `mayGetWet` and so on — so the set of keys varies by entity and by park; read the ones you need and ignore the rest rather than expecting a fixed shape. For what the entity is doing right now, GET /v1/entity/{id}/live. Cached `public, max-age=300, s-maxage=3600`: this changes when a park changes its data, which is rarely, and polling it faster buys requests rather than freshness. + * Get an entity + * @description Returns what this entity is: its name, entityType, timezone, location, parent and park, and its attributes. `id` can be an entity's UUID, its slug or, for a destination, its `externalId`. An unknown or malformed id returns 404. Attributes appear as extra top-level keys named after them, such as `minimumHeight` and `mayGetWet`, so the set of keys varies; read the ones you need. For what the entity is doing now, call GET /v1/entity/{id}/live. */ get: operations["getEntityById"]; put?: never; @@ -52,8 +52,8 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/children - * @description The entities beneath this one, as a flat array — id, name, entityType, slug, external id, coordinates and parentId each. `id` is an entity's UUID, its slug, or — for a destination only — its upstream external id. An id that resolves to nothing is 404, including one malformed enough that the query itself rejects it. HOW FAR DOWN depends on what you asked about, and this is the part clients get wrong: a DESTINATION returns every entity in the destination and a PARK returns every entity in the park — the whole subtree, not one level — while every other entityType returns its direct children only. Rebuild the hierarchy from `parentId` rather than assuming one level. Soft-deleted entities are never included. Cached `public, max-age=300, s-maxage=3600`. + * List the entities inside an entity + * @description Returns the entities beneath this one as a flat array, each with id, name, entityType, slug, externalId, location and parentId. `id` can be an entity's UUID, its slug or, for a destination, its `externalId`. An unknown or malformed id returns 404. For a DESTINATION or a PARK you get everything inside it, not just one level; for any other entityType you get its direct children. Rebuild the tree from `parentId`. Removed entities are not listed. */ get: operations["getEntityChildren"]; put?: never; @@ -72,8 +72,12 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/history - * @description History of an entity as one row per change, every row the complete live-data object at that instant (same keys as /live) plus `time` and `changed`. Ask for a park-local day (`date=YYYY-MM-DD`), a range of days (`from`/`to`, inclusive), or RFC 3339 instants with an offset (half-open). No parameters means today. At most 31 days per call. `opening` is the state effective at the start of the range; `coverage.firstRecordedAt` is the first day this entity has any history. Anonymous callers see 7 days, a free API key 30; deeper ranges return 403 HISTORY_WINDOW_EXCEEDED with the earliest allowed date. History requests have their own hourly budget, separate from the per-minute REST limit: 60 an hour without a key, 600 with a free key, 1200 on Pro, 3000 on Business, unmetered on Enterprise (published per tier in GET /tiers as limits.historyRequestsPerHour); over it returns 429 HISTORY_RATE_LIMITED with retryAfter. The per-minute REST limit still applies first and answers with the API-wide 429 body. A range that includes TODAY may be up to an hour old for callers without an API key, so a poller can see a response up to an hour behind the live feed; completed days are cached for longer because they cannot change. For the current state of an entity rather than its history, GET /v1/entity/{id}/live is not cached that way. FOR A PARK, this path answers the WHOLE PARK and the 200 is a different schema: `HistoryParkRawEnvelope`, carrying an `entities[]` array — one entry per entity of the park that has history, ascending by name, the park itself included when it has history of its own — each entry holding the same `coverage`, `opening` and `history` block a single entity gets. An entity with no history is absent from that array rather than present and empty. A park range is 1 park-local day, not 31: a day of a park is every recorded change for every entity in it, so a wider range is 400 RANGE_TOO_LONG and the call is never paged. Every other entityType — a DESTINATION included — returns the single-entity envelope described above, so the 200 is a union of two schemas and the entity's `entityType` is what selects between them. Either way the call costs ONE unit of the hourly history budget, whatever the park's size. + * History of an entity + * @description Returns an entity's history as one row per change. Each row is the entity's complete live data at that moment (the same keys as /live) plus `time` and `changed`. Ask for one park-local day (`date=YYYY-MM-DD`), a range of days (`from` and `to`, both inclusive), or RFC 3339 instants with an offset (`to` exclusive). With no parameters you get today. A call covers up to 31 days. The `opening` object is the state at the start of the range: the last reading of every field, however old, with `opening.observedAt` saying when it was seen, so the first row is already complete. `coverage.firstRecordedAt` is the first day we hold anything for this entity. + * + * For a park, the 200 is `HistoryParkRawEnvelope`: an `entities[]` array with the same `coverage`, `opening` object and `history` for each entity that has history, the park included if it has its own. A park call covers 1 park-local day, and a longer range returns 400 RANGE_TOO_LONG. Every other entityType gets the single-entity shape, so the 200 is a union of two schemas selected by `entityType`. A call costs one unit of the hourly history budget, however large the park. + * + * See "Limits" above for the history window and hourly budget. */ get: operations["getHistory"]; put?: never; @@ -92,8 +96,10 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/history/coverage - * @description What history we hold for this entity, broken down per live-data field: the first and last park-local day each field (`status`, `queue.STANDBY`, `showtimes`, and so on) was reported, keyed by the same live-data path GET /v1/entity/{id}/live and GET /v1/entity/{id}/history and .../history/daily use, so a key matches straight across all four. A field the entity never reported is ABSENT from `kinds`. Read `last` as "newest day in the ARCHIVE", not "last day reported": the archive is written two to three days behind live data, so a field being published right now still has a `last` a few days old, and an active field is indistinguishable from a withdrawn one here. To ask whether a field is still live, call GET /v1/entity/{id}/live. For how recent a day you can actually ASK for, read `retrievableThrough`: history calls serve recent readings as well as the archive, so it is normally TODAY for an entity still reporting and therefore sits two to three days AHEAD of `lastRecordedAt` — that gap is expected, not a fault. For an entity that stopped reporting long ago it equals `lastRecordedAt`, so it never promises data that is not there. `firstRecordedAt` and `lastRecordedAt` are the entity-wide ARCHIVE bounds; an entity with nothing recorded returns the document with both null and `kinds: {}`, never a 404 — "we hold nothing for this entity" is a real, actionable answer, and a different claim from "this entity does not exist". No parameters, no paging and no tier window: the document is the same handful of day strings whatever the entity's history depth, so this call is not entitlement-gated. It still shares the hourly history budget with GET /v1/entity/{id}/history and .../history/daily, separate from the per-minute REST limit: 60 an hour without a key, 600 with a free key, 1200 on Pro, 3000 on Business, unmetered on Enterprise (published per tier in GET /tiers as limits.historyRequestsPerHour); over it returns 429 HISTORY_RATE_LIMITED with retryAfter. The per-minute REST limit still applies first and answers with the API-wide 429 body. The response is the same bytes for every caller, so it is publicly cacheable for an hour — every value in it is a whole day, so a cached copy can only differ from a fresh one in the first hour after park-local midnight, when `retrievableThrough` may still name the previous day. + * History held for an entity + * @description Returns the history we hold for this entity, per field: the first and last park-local day we recorded each field (`status`, `queue.STANDBY`, `showtimes` and so on), keyed by the same live-data paths as /live, /history and /history/daily. Fields the entity never reported are left out of `kinds`. Recording runs 2 to 3 days behind live data, so `last` and `lastRecordedAt` usually trail today by that much, even for a field still being published; use /live to see what is current. `retrievableThrough` is the newest day you can ask /history and /history/daily for, usually today. An entity with nothing recorded returns `kinds: {}` with null days, not 404. For a park, the 200 is `HistoryParkCoverageDocument`, a summary across the park's entities. This call takes no parameters, is not paged and has no history window, but it does spend the hourly history budget. + * + * See "Limits" above for the history window and hourly budget. */ get: operations["getHistoryCoverage"]; put?: never; @@ -112,8 +118,24 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/history/daily - * @description One summary row per park-local day: how long the entity was OPERATING and DOWN, when it first opened and last closed, minute-weighted standby and single-rider wait statistics, a show count where the entity publishes showtimes, and how many changes were recorded. Ask for a park-local day (`date=YYYY-MM-DD`), a range of days (`from`/`to`, inclusive), or RFC 3339 instants with an offset; `range` always comes back as park-local days, because a row summarises a whole day. No parameters means today. At most 3660 days per call, and the response is never paged. A day with no data is ABSENT from `days` — there is no row of zeroes, because "we have nothing for this day" is a different claim from "observed, closed all day" — and `standby`, `singleRider` and `showCount` are omitted rather than null when the entity published nothing of that kind. `coverage.firstRecordedAt` is the first day this entity has any history. Anonymous callers see 7 days, a free API key 30; deeper ranges return 403 HISTORY_WINDOW_EXCEEDED with the earliest allowed date. These calls share the hourly history budget with GET /v1/entity/{id}/history, separate from the per-minute REST limit: 60 an hour without a key, 600 with a free key, 1200 on Pro, 3000 on Business, unmetered on Enterprise (published per tier in GET /tiers as limits.historyRequestsPerHour); over it returns 429 HISTORY_RATE_LIMITED with retryAfter. The per-minute REST limit still applies first and answers with the API-wide 429 body. FOR A PARK, this path answers the WHOLE PARK and the 200 is a different schema: `HistoryParkDailyEnvelope`, carrying an `entities[]` array — one entry per entity of the park that has history, ascending by name, the park itself included when it has history of its own — instead of this envelope's `coverage` and `days`. An entity with no history is absent from that array rather than present and empty. A park call is also the one PAGED call in this family: it serves at most 31 park-local days and `next` is an absolute URL for the rest, with your other parameters preserved. Every other entityType — a DESTINATION included — returns the single-entity envelope described above, so the 200 is a union of two schemas and the entity's `entityType` is what selects between them. Either way the call costs ONE unit of the hourly history budget, whatever the park's size. + * Daily summaries of an entity's history + * @description Returns one summary row per park-local day: minutes operating, down and unknown, first opening and last close, wait statistics, show count and change count. Parameters are as for /history; rows cover whole days. A call covers up to 3660 days and is never paged. Days with no data are left out. So are `standby`, `singleRider` and `showCount` when there was nothing of that kind. + * + * A run lasts from a change to OPERATING until the next change to CLOSED or REFURBISHMENT, DOWN periods included. A row is counted like this: + * + * - An OPERATING status that has not changed for 4 hours or more counts as `unknownMinutes`, not `operatingMinutes`, outside the park's published hours or on a day with none. A status carried in from before midnight counts as already that old. Inside published hours, a carried OPERATING status counts as operating. + * - A wait counts only while the entity is OPERATING and on the day it was posted. The wait showing when a ride opens counts if it last changed within 24 hours. + * - `extremeWaits` counts readings of 480 minutes or more, usually feed errors. Nothing is left out: those readings stay in the statistics, and `extremeWaits` flags them. + * - `firstOperatingAt` is null when the entity did not change to OPERATING that day; it may still have operated, carried over from the day before. + * - `lastClosedAt` is when the last run that started that day closed, which can be after midnight. The next day's row does not repeat it. + * - `inParkHours` repeats the numbers for the park's published hours, when it published any. + * - A row without `unknownMinutes` was counted under earlier rules. + * + * To rebuild a row from /history, use that day's and the next day's history, the park's schedule for both days, and `opening.observedAtByKind`. + * + * For a park, the 200 is `HistoryParkDailyEnvelope`, with an `entities[]` array in place of `coverage` and `days`. Park calls are paged, 31 park-local days at a time, with `next` for the rest. Every other entityType gets the single-entity shape, so the 200 is a union of two schemas selected by `entityType`. A call costs one unit of the hourly history budget, however large the park. + * + * See "Limits" above for the history window and hourly budget. */ get: operations["getHistoryDaily"]; put?: never; @@ -132,8 +154,8 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/live - * @description Live data for this entity AND everything beneath it, in one call: wait times, ride status, return-time and boarding-group windows, and show times. `id` is an entity's UUID, its slug, or — for a destination only — its upstream external id. An id that resolves to nothing is 404, including one malformed enough that the query itself rejects it. An entity with nothing to report is absent from `liveData` rather than present and empty, so treat a missing entry as no data rather than as a closed ride. `?entityType=ATTRACTION,SHOW` filters the array to those types (comma-separated). Cached `public, max-age=60, s-maxage=60`: the collectors run on a cadence, and a faster poll returns the same body. For what an entity reported in the past rather than now, GET /v1/entity/{id}/history. + * Live data for an entity + * @description Returns live data for this entity and everything beneath it: status, wait times, return-time and boarding-group windows, and show times. `id` can be an entity's UUID, its slug or, for a destination, its `externalId`. An unknown or malformed id returns 404. An entity with nothing to report is left out of `liveData`; treat that as no data. Filter by type with `entityType`. The data is current to about a minute. For past data, call GET /v1/entity/{id}/history. */ get: operations["getEntityLiveData"]; put?: never; @@ -152,8 +174,8 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/schedule - * @description Opening hours for this entity, for the default window: today through the next 30 days, anchored to the entity's own timezone rather than the caller's or UTC. `id` is an entity's UUID, its slug, or — for a destination only — its upstream external id. An id that resolves to nothing is 404, including one malformed enough that the query itself rejects it. Days the park has not published are absent from the array rather than present as closed. For a specific month, including a past one, use GET /v1/entity/{id}/schedule/{year}/{month}. Cached `public, max-age=300, s-maxage=3600`. + * Upcoming opening hours + * @description Returns opening hours from today through the next 30 days, in the entity's own timezone. `id` can be an entity's UUID, its slug or, for a destination, its `externalId`. An unknown or malformed id returns 404. Days the park has not published are left out. For a particular month, past months included, call GET /v1/entity/{id}/schedule/{year}/{month}. */ get: operations["getEntitySchedule"]; put?: never; @@ -172,8 +194,8 @@ export interface paths { cookie?: never; }; /** - * GET /v1/entity/{id}/schedule/{year}/{month} - * @description Opening hours for one calendar month in the entity's own timezone. `month` is TWO digits, 01-12 — `/2026/9` is 400, `/2026/09` is right — and `year` is a four-digit year between 1970 and 2150; anything else is 400 before the entity is even looked up. `id` is an entity's UUID, its slug, or — for a destination only — its upstream external id. An id that resolves to nothing is 404, including one malformed enough that the query itself rejects it. Past months are served from what was recorded at the time and are not backfilled, so a month before this entity was collected comes back empty rather than 404. Days the park has not published are absent rather than present as closed. Cached `public, max-age=300, s-maxage=3600`. + * Opening hours for a month + * @description Returns opening hours for one calendar month, in the entity's own timezone. `month` must be two digits (`/2026/09`, not `/2026/9`) and `year` a number from 1970 to 2150; anything else returns 400. `id` can be an entity's UUID, its slug or, for a destination, its `externalId`. An unknown or malformed id returns 404. Past months show what was published at the time. A month before we started recording this entity comes back empty. Days the park has not published are left out. */ get: operations["getEntityScheduleYearMonth"]; put?: never; @@ -184,10 +206,49 @@ export interface paths { patch?: never; trace?: never; }; + "/v1/me": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Your plan and remaining budgets + * @description Returns your plan and what is left of it: `tier`, how far back your history calls reach (`historyDays`, or `historyAllArchive: true` when you can read everything we hold), the earliest day you may ask for, and two budgets: `rateLimit`, the request limit every call counts against, and `historyRateLimit`, the hourly history budget. Each budget has `unmetered`; when it is false, it also has `limit`, `windowSeconds`, `remaining` and `reset`, the same figures as the RateLimit headers. Use it on an unmetered plan, which gets no such headers, or to check your history budget without spending it. The call counts as one ordinary request and needs an API key. + */ + get: operations["getMe"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { schemas: { + /** @description 401: this endpoint needs an API key (X-API-Key header) or a session token, and none was sent or the one sent was not accepted. A revoked, mistyped or truncated key answers this too. */ + AuthenticationRequired: { + /** + * @description Always false. + * @enum {boolean} + */ + success: false; + error: { + /** @enum {string} */ + type: "Authentication failed"; + /** @description Says whether no credential was sent or the one sent was not accepted. */ + message: string; + /** + * @description Repeats the HTTP status. + * @enum {integer} + */ + code?: 401; + }; + }; /** * @description State of boarding group availability * @enum {string} @@ -200,7 +261,7 @@ export interface components { name: string; /** @description URL-friendly slug for the destination */ slug?: string | null; - /** @description External entity ID from the source data provider */ + /** @description The park operator's own id for this destination */ externalId?: string | null; /** @description Array of parks within this destination */ parks: components["schemas"]["Park"][]; @@ -239,7 +300,7 @@ export interface components { timezone?: string; children?: components["schemas"]["EntityChild"][]; }; - /** @description A single entity. Beyond the properties listed here, an entity may carry additional tag-derived properties named after the tag's slug, for example `minimumHeight` (integer, centimetres) or `mayGetWet` (boolean). The set is open-ended and driven by data rather than fixed by this contract, so clients should read them defensively rather than assume any particular tag is present. */ + /** @description A single entity. It may also carry attribute keys not listed here, named after the attribute, e.g. `minimumHeight` (integer, centimetres) or `mayGetWet` (boolean). Which ones appear varies by entity, so read the ones you need and do not assume any is present. */ EntityData: { /** @description Unique entity identifier */ id: string; @@ -260,17 +321,17 @@ export interface components { /** @description Entity timezone */ timezone: string; location?: components["schemas"]["EntityLocation"]; - /** @description Identifier used by the source data provider. */ + /** @description The park operator's own id for this entity. */ externalId?: string; /** @description URL-friendly slug. Served for destinations. */ slug?: string | null; } & { [key: string]: unknown; }; - /** @description 400: a path parameter is the wrong shape. Checked before the entity is looked up, so a bad `year` or `month` answers 400 whether or not the id exists. */ + /** @description 400: a path parameter is the wrong shape, such as a one-digit `month` or a `year` outside the accepted range. An unknown id returns 404 first. */ EntityInvalidParameter: { /** - * @description Always false. Branch on this rather than on the status alone. + * @description Always false. * @enum {boolean} */ success: false; @@ -319,10 +380,10 @@ export interface components { /** @description Longitude coordinate of the entity location */ longitude?: number | null; }; - /** @description 404: nothing resolved from `id`. An id is a UUID, a slug, or — for a destination — its upstream external id; an id malformed enough that the lookup itself rejects it answers 404 as well, rather than 400 or 500. The body is the same whether the entity never existed or has been removed, so it cannot be used to tell those apart. */ + /** @description 404: nothing matches `id` (a UUID, a slug, or a destination's externalId; a malformed id is 404 too). The answer is the same whether it never existed or was removed. */ EntityNotFound: { /** - * @description Always false. Branch on this rather than on the status alone. + * @description Always false. * @enum {boolean} */ success: false; @@ -359,11 +420,11 @@ export interface components { HistoryCoverage: { /** * Format: date - * @description First park-local day with recorded history for this entity, or null when nothing has been archived yet. Per-kind detail and gaps: GET /v1/entity/{id}/history/coverage. + * @description First park-local day we hold anything for this entity, or null. Per-field detail: GET /v1/entity/{id}/history/coverage. */ firstRecordedAt: string | null; }; - /** @description What history is actually held for one entity, broken down per live-data field. Two different questions, answered separately: `firstRecordedAt`/`lastRecordedAt` and the per-field spans describe the ARCHIVE, while `retrievableThrough` is the newest day a history call could return for this entity — which is normally today, and normally two to three days AHEAD of `lastRecordedAt`. An entity with nothing recorded is a 200 with kinds: {} and every day null, never a 404: "we hold nothing for this entity" is a real, actionable answer and a different claim from "this entity does not exist". */ + /** @description What history we hold for one entity, per field. An entity with nothing recorded is a 200 with `kinds: {}` and null days, not 404. For a PARK the same call returns HistoryParkCoverageDocument. */ HistoryCoverageDocument: { id: string; name: string; @@ -374,20 +435,20 @@ export interface components { timezone: string; /** * Format: date - * @description First park-local day with any recorded history for this entity, or null when nothing has been archived yet. May legitimately be earlier than any individual kind's first: the two are recorded independently and answer slightly different questions. + * @description First park-local day we hold anything for this entity, or null. */ firstRecordedAt: string | null; /** * Format: date - * @description The newest `last` across `kinds` — the most recent park-local day we hold anything at all for this entity — or null when nothing is recorded. Like the per-field `last`, this tracks the ARCHIVE and lags live data by two to three days, so it sits in the past for an entity reporting normally. + * @description The newest `last` across `kinds`, or null. */ lastRecordedAt: string | null; /** * Format: date - * @description The newest park-local day GET /v1/entity/{id}/history and .../history/daily could return data for this entity — what you can ASK FOR, as opposed to what has been filed. Normally TODAY for an entity still reporting, because those endpoints answer from recent readings as well as the archive, and it therefore sits AHEAD of `lastRecordedAt` by two to three days for a healthy entity. That gap is the whole point of this field: `lastRecordedAt` and every per-field `last` describe the ARCHIVE only, and reading them as capability is what makes coverage look as though it has stopped a couple of days short. It is the LATER of `lastRecordedAt` and the newest day recent readings can still answer for — so an entity that stopped reporting long ago reports its archive day here, NOT today, and the field never promises data that is not there. Recent readings do not go back indefinitely, so a day is reported here only if one of those endpoints can actually return it: an entity whose last reading is old enough falls back to its archive day rather than naming the day that reading was taken. Null only when we hold nothing for this entity in either place. A request for a range up to this day can still be narrowed by your tier's history window, which bounds how far BACK you may ask, never how recent. + * @description The newest day you can ask /history and /history/daily for: usually today for an entity still reporting, or its last recorded day for one that stopped long ago. Null when we hold nothing. Your history window limits how far back you can ask. */ retrievableThrough: string | null; - /** @description Keyed by LIVE-DATA PATH (status, queue.STANDBY, showtimes, ...), not by the internal kind name, so a key matches straight against what GET /v1/entity/{id}/live and GET /v1/entity/{id}/history return. A kind the entity never reported is ABSENT here and absent from every /history row — there is no zero-span entry for it. See `last` for why a span ending in the past does NOT mean the field stopped being reported: the archive lags live data by two to three days, so an actively published field ends in the past too. Every span here is archive-only; `retrievableThrough` is the entity-wide answer to how recent a day you can actually ask for. */ + /** @description Keyed by live-data path (status, queue.STANDBY, showtimes and so on), as /live and /history name them. Fields the entity never reported are left out. */ kinds: { [key: string]: components["schemas"]["HistoryCoverageKindSpan"]; }; @@ -401,11 +462,11 @@ export interface components { first: string; /** * Format: date - * @description Newest park-local day this field appears in the ARCHIVE. This is not the same as the last day the field was reported, and it does NOT mean the field has stopped: the archive is written two to three days behind live data, so a field being published right now still has a `last` a few days in the past. Every active field looks the same as a withdrawn one here. Use this to know how far back the archive goes and how current it is, not to decide whether a field is still live — GET /v1/entity/{id}/live answers that directly. + * @description The newest day we hold this field for. The coverage call says how far it trails today. */ last: string; }; - /** @description A day-by-day summary of one entity's history. GET /v1/entity/{id}/history/daily returns this shape for every entityType EXCEPT PARK; for a PARK the same path returns HistoryParkDailyEnvelope, which carries an entities[] array instead of this envelope's coverage/days block. range.from and range.to ALWAYS echo park-local calendar days (YYYY-MM-DD), even when the call supplied RFC 3339 instants, because this endpoint summarises whole park-local days and an instant echo would claim a precision the rows do not have. TODAY's row is the day so far — its counters cover only elapsed minutes and grow as the day does — and a response to a request without an API key may be up to an hour old, so a poller can see a value that far behind the live feed. If you need the current state of an entity rather than its day so far, GET /v1/entity/{id}/live is not cached that way. */ + /** @description One entity's daily summary. For a PARK the same call returns HistoryParkDailyEnvelope. range is always whole park-local days (YYYY-MM-DD), and today's row is the day so far. */ HistoryDailyEnvelope: { id: string; name: string; @@ -416,12 +477,33 @@ export interface components { timezone: string; range: components["schemas"]["HistoryRange"]; coverage: components["schemas"]["HistoryCoverage"]; - /** @description One row per park-local day, ascending by date. A day with no data is ABSENT: there is no row of zeroes, because "we have nothing for this day" is a different claim from "observed, closed all day". */ + /** @description One row per day, ascending. Days with no data are left out. */ days: components["schemas"]["HistoryDailyRow"][]; - /** @description URL of the next page, or null. Always null for a single entity: a daily call is unpaged. Park calls page; see HistoryParkDailyEnvelope. */ + /** @description Always null for a single entity. */ next: string | null; }; - /** @description One park-local day of an entity's history reduced to the numbers a crowd calendar needs. standby, singleRider and showCount are ABSENT rather than null when there is nothing to report: an absent standby means no numeric standby wait was in force while OPERATING for a whole sampled minute that day — the statistics are sampled at minute resolution, so a wait published only inside a sub-minute window produces no block at all, even though /history records it and the day's operatingMinutes count it. The same applies to singleRider. An absent showCount means the entity published no showtimes. showCount counts distinct performance start times in the local day. */ + /** @description How many wait readings of 480 minutes or more the day's statistics include. Such readings are usually feed errors (values like 999); they are counted here as a flag and stay in every statistic. Counted per reading while OPERATING. Present only when there were some, and then with both counts. */ + HistoryDailyExtremeWaits: { + /** @description Standby readings of 480 minutes or more included in the day's standby statistics. */ + standby: number; + /** @description Single-rider readings of 480 minutes or more included in the day's single-rider statistics. */ + singleRider: number; + }; + /** @description The day's numbers limited to the park's published hours. Present only when the park published hours that day. */ + HistoryDailyInParkHours: { + /** @description Minutes of the day inside the park's published hours: its schedule entries of type OPERATING, EXTRA_HOURS and TICKETED_EVENT. Hours from the previous day's schedule that run past midnight are not included. Today counts elapsed minutes only. */ + scheduledMinutes: number; + /** @description Of scheduledMinutes, the minutes the entity was OPERATING. */ + operatingMinutes: number; + /** @description Of scheduledMinutes, the minutes the entity was DOWN. */ + downMinutes: number; + /** @description Of scheduledMinutes, the minutes with no known status. */ + unknownMinutes: number; + standby?: components["schemas"]["HistoryDailyStats"]; + singleRider?: components["schemas"]["HistoryDailyStats"]; + extremeWaits?: components["schemas"]["HistoryDailyExtremeWaits"]; + }; + /** @description One day of an entity's history. standby, singleRider, extremeWaits, showCount and inParkHours are absent when there is nothing to report; a standby block needs a valid wait showing for at least one whole minute. A row without unknownMinutes was counted under earlier rules, and also lacks extremeWaits and inParkHours. */ HistoryDailyRow: { /** * Format: date @@ -430,39 +512,43 @@ export interface components { date: string; /** * Format: date-time - * @description UTC instant (whole seconds) the entity first became OPERATING on this park-local day, or null if it never did. A day that opened already OPERATING reports the start of the local day. + * @description When the entity changed to OPERATING that day (UTC, whole seconds). null when it did not change to OPERATING that day; it may still have operated, carried over from the day before. */ firstOperatingAt: string | null; /** * Format: date-time - * @description UTC instant (whole seconds) of the last transition out of OPERATING or DOWN into CLOSED or REFURBISHMENT after firstOperatingAt, or null if there was none. For a park closing after local midnight this instant falls on the following UTC day. + * @description When the last run that started this day closed (UTC, whole seconds). A run lasts from a change to OPERATING until the next change to CLOSED or REFURBISHMENT, DOWN periods included. A run still going at midnight closes the next day and is reported on this row. null if it did not close by the end of the next day, or if the close came after 4 hours or more unchanged outside published hours. */ lastClosedAt: string | null; - /** @description Minutes of this park-local day the entity was OPERATING. Minutes with no observed state count as neither operating nor down, so the two counters need not add up to the length of the day. For TODAY the count covers only the minutes that have already elapsed, so it grows through the day and is final once the day ends: a caller polling today's row sees it rise, which is the day filling in rather than the answer changing. */ + /** @description Minutes OPERATING with a known status. Today counts elapsed minutes only. CLOSED and REFURBISHMENT minutes are not counted, so operatingMinutes, downMinutes and unknownMinutes need not add up to the day. */ operatingMinutes: number; - /** @description Minutes of this park-local day the entity was DOWN. As with operatingMinutes, today's count covers only the elapsed part of the day. */ + /** @description Minutes DOWN. Today counts elapsed minutes only. */ downMinutes: number; + /** @description Minutes with no known status: none was reported, or OPERATING had not changed for 4 hours or more outside the park's published hours (or on a day with none). A status carried over midnight counts as already 4 hours old. Absent on rows counted under earlier rules. */ + unknownMinutes?: number; standby?: components["schemas"]["HistoryDailyStats"]; singleRider?: components["schemas"]["HistoryDailyStats"]; + extremeWaits?: components["schemas"]["HistoryDailyExtremeWaits"]; /** @description Distinct performance start times whose park-local day is this day. Present only for entities that published showtimes on the day. */ showCount?: number; - /** @description Number of history rows recorded on this day, i.e. instants at which any kind changed. Short flaps are counted as they happened; this is not a cleaned figure. */ + inParkHours?: components["schemas"]["HistoryDailyInParkHours"]; + /** @description How many times any field changed this day. */ changes: number; }; - /** @description Wait statistics for one park-local day. The percentiles and the mean are weighted by the MINUTES the wait was posted rather than by the number of readings, so a wait that stood for three hours counts three hours and a brief flap does not drag the median; they are sampled at minute resolution and the percentiles are nearest-rank, never interpolated. `min` and `max` are TRUE extremes over every value posted, so a spike too short to be sampled still shows there. Only periods where the entity was OPERATING and published a numeric wait count at all. The block is absent when it never did. */ + /** @description Wait statistics for the day. p50, mean and p90 are weighted by how many minutes each wait was showing; min and max are the extremes of every value posted. Only minutes where the entity was OPERATING (not unknown) and the wait was valid count. A wait is valid during the run and on the day it was posted; the wait showing when a ride opens counts from the opening if it last changed within 24 hours; a wait carried over midnight does not count until it changes. Nothing the park reported is excluded: a reading of 480 minutes or more stays in these statistics and is counted in the row's `extremeWaits`. Absent when no minute counted. */ HistoryDailyStats: { - /** @description Lowest wait, in minutes, the entity published while OPERATING that day. A true extreme over every value posted, including one that stood for less than a minute — so unlike the percentiles below it is not minute-weighted. */ + /** @description Lowest wait posted during the counted minutes, including one that showed for under a minute. */ min: number; - /** @description Median wait, nearest-rank over the minute weights (a value actually posted, never interpolated). */ + /** @description Median wait, weighted by minutes; always a value that was actually posted. */ p50: number; /** @description Minute-weighted average wait, rounded to the nearest whole minute. */ mean: number; - /** @description 90th-percentile wait, nearest-rank over the minute weights. */ + /** @description 90th-percentile wait, weighted by minutes. */ p90: number; - /** @description Highest wait, in minutes, the entity published while OPERATING that day. A true extreme, as min is: a spike that lasted forty seconds counts here and is invisible to the percentiles, which is the intended difference between the two halves of this block — extremes answer "what did it ever reach", percentiles answer "what was it usually like". */ + /** @description Highest wait posted during the counted minutes, including a brief spike. It can be a feed error: the row's extremeWaits counts readings of 480 minutes or more. */ max: number; }; - /** @description One entity's history as full-state change rows. GET /v1/entity/{id}/history returns this shape for every entityType EXCEPT PARK; for a PARK the same path returns HistoryParkRawEnvelope, which carries an entities[] array instead of this envelope's coverage/opening/history block. */ + /** @description One entity's history. For a PARK the same call returns HistoryParkRawEnvelope instead. */ HistoryEnvelope: { id: string; name: string; @@ -476,10 +562,10 @@ export interface components { opening: components["schemas"]["HistoryOpening"]; /** @description Ascending by time. */ history: components["schemas"]["HistoryRow"][]; - /** @description URL of the next page, or null. Always null for a single entity (a call covers up to 31 days). Park calls page; see HistoryParkRawEnvelope. */ + /** @description Always null for a single entity. */ next: string | null; }; - /** @description 502: the range needs archived history and that backend is temporarily unavailable. The request is retryable. */ + /** @description 502: history is temporarily unavailable. Retry shortly. */ HistoryErrorBackendUnavailable: { error: { /** @enum {string} */ @@ -513,16 +599,16 @@ export interface components { message: string; }; }; - /** @description 400: the range is longer than the path allows. The cap is NOT the same on every path, and this one error type is returned by all of them: GET /v1/entity/{id}/history allows 31 park-local days for a single entity and 1 for a PARK; GET /v1/entity/{id}/history/daily allows 3660 (ten years) for a single entity, and for a PARK serves 31 days a page and gives you `next` for the rest. The message names the cap that applied. Split the ask into consecutive calls. */ + /** @description 400: the range is too long. The limit is not the same on every path: 31 days on /history (1 for a park), and 3660 on /history/daily (a park pages at 31 instead). Split the range into shorter calls. */ HistoryErrorRangeTooLong: { error: { /** @enum {string} */ type: "RANGE_TOO_LONG"; - /** @description Names the cap that was exceeded and the span that was asked for, e.g. "A history call covers at most 31 park-local days (2026-01-01 to 2026-03-01 is 60). Ask for a shorter range." The number is the cap for the path that answered, not a constant: read it from the message rather than hard-coding 31. */ + /** @description Names the limit that applied and your span, e.g. "A history call covers at most 31 park-local days (2026-01-01 to 2026-03-01 is 60)." */ message: string; }; }; - /** @description 429: the caller's hourly history request budget is spent. The budget is separate from the per-minute REST limit and is published per tier in GET /tiers as limits.historyRequestsPerHour (anonymous.historyRequestsPerHour for keyless calls). */ + /** @description 429: your hourly history budget is spent. It is separate from the per-minute limit; the limits per plan are on the pricing page. */ HistoryErrorRateLimited: { error: { /** @enum {string} */ @@ -537,7 +623,7 @@ export interface components { error: { /** @enum {string} */ type: "HISTORY_WINDOW_EXCEEDED"; - /** @description A fact and a date, naming no plan and selling nothing. e.g. "This key can see history back to 2026-09-08 (7 days).", or "Requests without an API key can see history back to 2026-09-08 (7 days)." when you sent no key. */ + /** @description e.g. "This key can see history back to 2026-09-08 (7 days)." */ message: string; /** * Format: date @@ -546,7 +632,7 @@ export interface components { earliestAllowedDate: string; }; }; - /** @description The full live-data state effective at the start of the range, in the same shape as a row. A key is present only when the entity has that kind. When the value is unknown at that instant (typically an older range, answered from the archive rather than from recent readings) the kind carries its EMPTY live value rather than a null container — an unknown standby is {"waitTime": null}, an unknown showtimes list is [] — and status, which has no empty value, is null. */ + /** @description The `opening` object: the complete state at the start of the range, in the same shape as a row. A field is present only if the entity has it. An unknown value is its empty form (standby `{"waitTime": null}`, showtimes `[]`); an unknown status is null. */ HistoryOpening: { /** * Format: date-time @@ -555,21 +641,29 @@ export interface components { time: string; /** * Format: date-time - * @description The UTC instant (whole seconds) at which this state was actually OBSERVED, as opposed to `time`, which is the start of the range you asked for. The two are different questions and only this one tells you whether to trust the state. - * - * A state carried forward from before the range has an `observedAt` BEFORE `time` — sometimes long before, because the lookup is deliberately unbounded and returns the last reading of each kind at any age. So a day we hold nothing for still reports the newest state we ever saw, which is usually right and occasionally very wrong: a ride whose feed simply stopped mid-operation carries its last wait time forward indefinitely. - * - * Compare it against `range.from` to decide. Equal to or after the range start means the state was seen inside the range. Before it means carried forward, and how far back you tolerate is yours to choose — a reading an hour before the day began is ordinary, one from three weeks earlier is not evidence about this day. Absent means nothing survives to carry: we can say nothing at all about the state at the start of this range. - * - * It is the NEWEST instant any kind in this opening was seen. Kinds can be observed at different moments, so an older kind may be staler than this field suggests; treat it as the most generous reading of the opening's age, not a guarantee about every key. Days that genuinely have data are better read from the rows, which carry their own `time`. + * @description When this state was last seen (UTC, whole seconds): the newest entry in `observedAtByKind`. Earlier than `time` means it was carried in from before the range, possibly from long ago; a ride whose feed stopped keeps its last values. Absent means we hold nothing for this entity from before the range, unless `degraded` is set. */ observedAt?: string; + /** @description When each field of the opening was last seen (UTC, whole seconds), keyed by its path: `status`, `queue.STANDBY`, `showtimes` and so on. A wait that did not change for weeks is dated weeks back, so check a queue's own entry before treating it as current. Usually, but not always, the moment the value last changed. */ + observedAtByKind?: { + [key: string]: string; + }; + /** + * @description Present, and true, when we could not look far enough back for this response, so the opening may be missing a field we hold. Ask again in a minute for the full opening. + * @enum {boolean} + */ + degraded?: true; + /** + * @description Why the lookup was cut short: `timeout`, `error`, or `capacity` when it needed more reading than one request is allowed. + * @enum {string} + */ + degradedReason?: "timeout" | "error" | "capacity"; /** @description Live status at the start of the range; null when unknown. */ status?: string | null; queue?: components["schemas"]["LiveQueue"]; showtimes?: components["schemas"]["LiveShowTime"][] | null; }; - /** @description How far back each entity's record of one field goes, as counts. Calendar years, measured from the day the document was built (`summary.measuredOn`). Counts, not a percentage or an average: a single figure for a park would hide that most of one park's standby entities have two to four years while its oldest reach back to the start of the archive. */ + /** @description How far back each entity's record of this field goes, as counts per band of calendar years, measured from `summary.measuredOn`. */ HistoryParkCoverageDepth: { /** @description Entities whose record of this field goes back four calendar years or more. */ fourYearsPlus: number; @@ -577,17 +671,17 @@ export interface components { twoToFourYears: number; /** @description Entities with at least one and under two calendar years. */ oneToTwoYears: number; - /** @description Entities with under a calendar year, typically something that opened recently rather than a gap. */ + /** @description Entities with under a calendar year, usually something that opened recently. */ underOneYear: number; }; - /** @description What history is held across a whole PARK. GET /v1/entity/{id}/history/coverage returns this shape when the entity is a PARK; every other entityType, a DESTINATION included, returns HistoryCoverageDocument for that entity alone. A park records nothing itself, so without this rollup the honest-looking answer for a park would be "nothing". It reports depth and breadth only: it does not detect missing days and does not judge whether a recorded value was correct. */ + /** @description What history we hold across a whole PARK, returned by /history/coverage when the entity is a PARK. Its names map to the single-entity document: `fields` is `kinds`, and each `from` and `newest` is a `first` and `last`. It reports depth and breadth; it does not find missing days. */ HistoryParkCoverageDocument: { id: string; name: string; entityType: string; parentId: string | null; destinationId: string | null; - /** @description IANA timezone the park-local days are resolved in. The park's children inherit it. */ + /** @description IANA timezone of the park. */ timezone: string; summary: components["schemas"]["HistoryParkCoverageSummary"]; /** @description Keyed by live-data field path, in live-data order. */ @@ -597,7 +691,7 @@ export interface components { /** @description Every entity of the park history is held for. */ entities: components["schemas"]["HistoryParkCoverageEntity"][]; }; - /** @description One entity of the park that history is held for. An entity nothing is held for is ABSENT rather than listed as empty: it is usually a parade, a show or a land, which never had a queue to record, and listing it would read as a gap. */ + /** @description One entity we hold history for. Entities with none (often parades, shows and lands) are absent. */ HistoryParkCoverageEntity: { id: string; name: string; @@ -612,12 +706,12 @@ export interface components { * @description The newest park-local day any field of this entity was recorded. */ newest: string; - /** @description The live-data field paths held for this entity, named exactly as the single-entity coverage document names them, so one client type reads both. */ + /** @description Field paths held, named as in the single-entity coverage document. */ fields: string[]; - /** @description False when the park no longer lists this entity. Its history is still held and still retrievable, and every count in this document includes it; this says where the entity is now, not what the archive has. */ + /** @description false when the park no longer lists this entity. Its history is still available. */ stillListed: boolean; }; - /** @description What one live-data field looks like across the whole park. `entities` counts what is HELD and is never a fraction: entities that have never reported this field are simply absent from the count, because a denominator drawn from entityType would publish parades, shows and lands as missing wait times. */ + /** @description One field across the park. `entities` counts the entities we hold it for; entities that never reported it are not counted. */ HistoryParkCoverageField: { /** @description How many of the park's entities this field is held for. */ entities: number; @@ -628,18 +722,18 @@ export interface components { from: string; /** * Format: date - * @description The newest park-local day any entity in the park reported it. A day in the past is not staleness: when a park stops publishing a field the ending is recorded, so the span genuinely stops there. + * @description Newest day any entity reported it. A past day can mean the park stopped publishing the field. */ newest: string; depth: components["schemas"]["HistoryParkCoverageDepth"]; }; - /** @description The park in four numbers. Every one describes what is held; none is a fraction of a total, and nothing here asserts that anything is missing. */ + /** @description Summary figures for the park, all describing what we hold. */ HistoryParkCoverageSummary: { - /** @description Entities of this park any live-data history is held for - attractions, restaurants, shows and anything else that has ever reported. Larger than the number with wait times: `fields` breaks it down. Counts entities the park no longer lists as well, since their history is still held; those carry `stillListed: false` in `entities`. */ + /** @description Entities we hold any history for, including ones the park no longer lists (`stillListed: false`). */ entitiesWithData: number; /** * Format: date - * @description The earliest park-local day anything in this park was recorded, or null when nothing has been. + * @description Earliest day anything in this park was recorded, or null. */ archiveFrom: string; /** @@ -649,71 +743,71 @@ export interface components { recordedTo: string; /** * Format: date - * @description The newest park-local day a caller can actually retrieve. Runs ahead of `recordedTo` by a day or two: the most recent days are served from live data before they are sealed into the archive. Null when nothing is recorded. + * @description The newest day you can ask for, usually today. Null when nothing is recorded. */ retrievableThrough: string; /** * Format: date - * @description The park-local day these figures were computed. They move as the archive grows, so a reader comparing two copies of this document needs to know which day each was built. + * @description The day these figures were computed; they grow over time. */ measuredOn: string; }; - /** @description A day-by-day summary of a whole PARK: every entity of the park that has history, in one call. GET /v1/entity/{id}/history/daily returns THIS shape when the entity is a PARK (entityType: "PARK") and HistoryDailyEnvelope for every other entityType, so a client should branch on the presence of entities[] or on the entity's type. range.from and range.to are always park-local calendar days, and range.to is THIS PAGE's last day rather than the whole range you asked for: a call serves at most 31 park-local days and next carries the rest. */ + /** @description The daily summary of a whole PARK, returned by /history/daily when the entity's entityType is PARK. A call serves up to 31 park-local days; `range.to` is this page's last day. */ HistoryParkDailyEnvelope: { id: string; name: string; entityType: string; parentId: string | null; destinationId: string | null; - /** @description IANA timezone the park-local days are resolved in. The park is the authority on where its day boundaries fall, so every entity below is summarised in THIS zone. */ + /** @description IANA timezone of the park; every entity is summarised in it. */ timezone: string; range: components["schemas"]["HistoryRange"]; - /** @description One entry per entity of the park that has history, ascending by name. An entity with no history is ABSENT — never an entry of nulls or an empty days[] — because "we hold nothing for this entity" is a different claim from "we hold nothing for these days". The park itself is included when it has history of its own. */ + /** @description One entry per entity with history, by name. Entities with no history are absent. */ entities: components["schemas"]["HistoryParkEntityDaily"][]; - /** @description Absolute URL of the next page, or null on the last one. A park daily call serves at most 31 park-local days and pages by DAY: the next URL repeats your other parameters with from advanced past this page's last day. Entity order never affects paging. */ + /** @description Absolute URL of the next page (your parameters kept, `from` moved on), or null on the last page. Up to 31 park-local days a page. */ next: string | null; }; - /** @description One entity of a park in a park DAILY response: its identity, the first day it has any history, and its day rows. The park itself appears as an entry too when it has history of its own (match it by id against the envelope's id). An entity with no history at all is ABSENT from entities[]. */ + /** @description One entity of the park, with its first recorded day and its rows. The park appears too if it has history of its own. */ HistoryParkEntityDaily: { id: string; name: string; entityType: string; coverage: components["schemas"]["HistoryCoverage"]; - /** @description One row per park-local day, ascending by date, exactly as GET /v1/entity/{id}/history/daily returns for this entity on its own. A day with no data is ABSENT, and an entity with history but nothing in the requested days has an empty array rather than vanishing from entities[] — so the entity list keeps its shape from one page to the next. */ + /** @description The entity's rows for this page, as /history/daily returns them for the entity alone. Empty when it has no data in these days. */ days: components["schemas"]["HistoryDailyRow"][]; }; - /** @description One entity of a park in a park RAW response: the same coverage, opening and history block GET /v1/entity/{id}/history returns for that entity on its own, so one client type reads both. The park itself appears as an entry too when it has history of its own (match it by id against the envelope's id). */ + /** @description One entity of the park, with the same coverage, opening and history as a single-entity call. The park appears too if it has history of its own. */ HistoryParkEntityRaw: { id: string; name: string; entityType: string; coverage: components["schemas"]["HistoryCoverage"]; opening: components["schemas"]["HistoryOpening"]; - /** @description Ascending by time. Empty when this entity recorded no change in the requested range, which is a different claim from having no history at all — an entity with no history is absent from entities[]. */ + /** @description Ascending by time. Empty when nothing changed in the range. */ history: components["schemas"]["HistoryRow"][]; }; - /** @description Full-state change rows for a whole PARK: every entity of the park that has history, in one call, for exactly 1 park-local day. GET /v1/entity/{id}/history returns THIS shape when the entity is a PARK (entityType: "PARK") and HistoryEnvelope for every other entityType, so a client should branch on the presence of entities[] or on the entity's type. A range spanning more than one day is 400 RANGE_TOO_LONG: a day of a park is every recorded change for every entity in it, and the one-day limit is what bounds that. Ask day by day. */ + /** @description History of a whole PARK for 1 park-local day, returned by /history when the entity's entityType is PARK. A longer range is 400 RANGE_TOO_LONG. */ HistoryParkRawEnvelope: { id: string; name: string; entityType: string; parentId: string | null; destinationId: string | null; - /** @description IANA timezone the park-local day is resolved in. The park is the authority on where its day boundaries fall, so every entity below is resolved in THIS zone. */ + /** @description IANA timezone of the park; every entity is resolved in it. */ timezone: string; range: components["schemas"]["HistoryRange"]; - /** @description One entry per entity of the park that has history, ascending by name. An entity with no history is ABSENT — never an entry of nulls — because "we hold nothing for this entity" is a different claim from "this entity recorded no change today". The park itself is included when it has history of its own. */ + /** @description One entry per entity with history, by name. Entities with no history are absent. */ entities: components["schemas"]["HistoryParkEntityRaw"][]; - /** @description Always null: a park history call covers one park-local day, so there is never a next page. */ + /** @description Always null: one day per call. */ next: string | null; }; HistoryRange: { - /** @description The requested start. A park-local day comes back verbatim (YYYY-MM-DD); an instant comes back NORMALISED to UTC whole seconds (2026-09-13T14:00:00Z), so an offset or sub-second precision you sent is not echoed back. On a day-granular endpoint such as /history/daily this is ALWAYS a park-local day, even when you asked with an instant: that endpoint's rows are whole days and cannot be sliced finer, so echoing your instant back would claim a precision the data does not have. */ + /** @description The start you asked for. A day comes back as you sent it; an instant comes back normalised to UTC whole seconds. On /history/daily it is always a day. */ from: string; - /** @description The requested end, in the same form as from, and normalised the same way. Omitted instants default to now; omitted days default to today, park-local. The same day-granular rule as from applies on /history/daily. */ + /** @description The end, in the same form as from. Defaults to today (days) or now (instants). */ to: string; }; - /** @description One row per instant at which any kind changed. Every present kind is carried forward, so a row is the complete live-data object at that instant (same keys, nesting and enum values as GET /v1/entity/{id}/live). */ + /** @description One row per moment any field changed. Every field is carried forward, so each row is the complete live data at that moment (same keys as GET /v1/entity/{id}/live). */ HistoryRow: { /** * Format: date-time @@ -726,6 +820,7 @@ export interface components { queue?: components["schemas"]["LiveQueue"]; showtimes?: components["schemas"]["LiveShowTime"][] | null; }; + /** @description The queues an entity has, each present only when the entity publishes it. STANDBY: the ordinary line. SINGLE_RIDER: a separate line for guests riding alone. RETURN_TIME: a free reservation for a later time window. PAID_RETURN_TIME: the same, paid for. BOARDING_GROUP: a virtual queue that calls groups by number. PAID_STANDBY: a paid line with its own wait. */ LiveQueue: { STANDBY?: { /** @description Current standby wait time in minutes */ @@ -790,7 +885,7 @@ export interface components { endTime?: string | null; }; /** - * @description Current operating status of an entity + * @description An entity's status. OPERATING: open and running. DOWN: stopped for now, for example by a breakdown, when it would otherwise be running. CLOSED: not open. REFURBISHMENT: closed for a longer period of maintenance or rebuilding. * @enum {string} */ LiveStatusType: "OPERATING" | "DOWN" | "CLOSED" | "REFURBISHMENT"; @@ -811,6 +906,18 @@ export interface components { timezone?: string; schedule?: components["schemas"]["ScheduleEntry"][]; }; + /** @description 503: your plan could not be read just now. Try again after the Retry-After header's number of seconds. */ + PlanUnavailable: { + /** @enum {boolean} */ + success: false; + error: { + /** @enum {string} */ + type: "Server error"; + message: string; + /** @enum {integer} */ + code?: 503; + }; + }; PriceData: { /** @description Numerical price amount, in the currency's lowest denomination (e.g. cents). null when the item costs money but the provider does not publish an amount; 0 means genuinely free */ amount: number | null; @@ -819,6 +926,17 @@ export interface components { /** @description Formatted price string */ formatted?: string; }; + /** @description 429 from the request limit every call counts against. See "Limits" at the top of this document. */ + RateLimited: { + /** @enum {string} */ + error: "Too Many Requests"; + /** @description What happened, e.g. "Too Many Requests". */ + message: string; + /** @description Seconds to wait before retrying. Also sent as the Retry-After header. */ + retryAfter: number; + /** @description Present when you were looking entities up one guessed slug at a time: the call to make instead, e.g. "GET /v1/destinations". */ + useInstead?: string; + }; /** * @description State of return time availability * @enum {string} @@ -867,6 +985,35 @@ export interface components { * @enum {string} */ SchedulePriceType: "ADMISSION" | "PACKAGE" | "ATTRACTION"; + /** @description Your plan and what is left of it. `rateLimit` is the request limit every call counts against, this one included. `historyRateLimit` is the hourly budget the history calls count against; reading it here does not spend it. Figures are per account, so every key on one account reports the same. */ + V1Me: { + /** @description Your plan, e.g. "free", "pro", "business", "enterprise". */ + tier: string; + /** @description How many days back your history calls may reach, today included. null when `historyAllArchive` is true. */ + historyDays: number | null; + /** @description true when this key can read everything we hold for an entity, back to the first day we recorded it. `historyDays` and `historyEarliestDate` are then null. */ + historyAllArchive: boolean; + /** + * Format: date + * @description The earliest day (YYYY-MM-DD) a history call may ask for, computed in UTC. Each park counts days in its own time zone, so near midnight this can be off by one. Earlier days answer 403 HISTORY_WINDOW_EXCEEDED. null when `historyAllArchive` is true. + */ + historyEarliestDate: string | null; + rateLimit: components["schemas"]["V1MeBudget"]; + historyRateLimit: components["schemas"]["V1MeBudget"]; + }; + /** @description One budget: the same figures the RateLimit-* and RateLimit-History-* headers carry. */ + V1MeBudget: { + /** @description true when this budget is not metered on your plan. The other fields are then absent, and no RateLimit headers are sent for it. */ + unmetered: boolean; + /** @description Requests allowed per window. */ + limit?: number; + /** @description Window length in seconds. */ + windowSeconds?: number; + /** @description Requests left in the current window; null if it could not be read just now. */ + remaining?: number | null; + /** @description Seconds until the window resets; null if nothing has been counted in this window yet, or if it could not be read. */ + reset?: number | null; + }; }; responses: never; parameters: never; @@ -894,23 +1041,13 @@ export interface operations { "application/json": components["schemas"]["DestinationsResponse"]; }; }; - /** @description Too Many Requests - Rate limit exceeded */ + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ 429: { headers: { [name: string]: unknown; }; content: { - "application/json": { - /** - * @description Error type - * @enum {string} - */ - error: "Rate limit exceeded"; - /** @description Rate limit exceeded message */ - message: string; - /** @description Time in seconds to wait before retrying */ - retryAfter?: number; - }; + "application/json": components["schemas"]["RateLimited"]; }; }; }; @@ -920,6 +1057,7 @@ export interface operations { query?: never; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -944,23 +1082,13 @@ export interface operations { "application/json": components["schemas"]["EntityNotFound"]; }; }; - /** @description Too Many Requests - Rate limit exceeded */ + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ 429: { headers: { [name: string]: unknown; }; content: { - "application/json": { - /** - * @description Error type - * @enum {string} - */ - error: "Rate limit exceeded"; - /** @description Rate limit exceeded message */ - message: string; - /** @description Time in seconds to wait before retrying */ - retryAfter?: number; - }; + "application/json": components["schemas"]["RateLimited"]; }; }; }; @@ -970,6 +1098,7 @@ export interface operations { query?: never; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -994,23 +1123,13 @@ export interface operations { "application/json": components["schemas"]["EntityNotFound"]; }; }; - /** @description Too Many Requests - Rate limit exceeded */ + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ 429: { headers: { [name: string]: unknown; }; content: { - "application/json": { - /** - * @description Error type - * @enum {string} - */ - error: "Rate limit exceeded"; - /** @description Rate limit exceeded message */ - message: string; - /** @description Time in seconds to wait before retrying */ - retryAfter?: number; - }; + "application/json": components["schemas"]["RateLimited"]; }; }; }; @@ -1018,12 +1137,16 @@ export interface operations { getHistory: { parameters: { query?: { + /** @description One park-local day, YYYY-MM-DD. Cannot be combined with from/to. */ date?: string; + /** @description Start: a park-local day (YYYY-MM-DD, inclusive) or an RFC 3339 instant with an offset (inclusive). from and to must be the same form. */ from?: string; + /** @description End: a day (inclusive) or an instant (exclusive). Defaults to today, or now. Up to 31 park-local days per call for a single entity. For a park, 1 park-local day, and a longer range returns 400 RANGE_TOO_LONG. */ to?: string; }; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -1072,10 +1195,10 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["HistoryErrorRateLimited"]; + "application/json": components["schemas"]["HistoryErrorRateLimited"] | components["schemas"]["RateLimited"]; }; }; - /** @description Upstream unavailable */ + /** @description Temporarily unavailable */ 502: { headers: { [name: string]: unknown; @@ -1091,6 +1214,7 @@ export interface operations { query?: never; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -1121,7 +1245,7 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["HistoryErrorRateLimited"]; + "application/json": components["schemas"]["HistoryErrorRateLimited"] | components["schemas"]["RateLimited"]; }; }; }; @@ -1129,12 +1253,16 @@ export interface operations { getHistoryDaily: { parameters: { query?: { + /** @description One park-local day, YYYY-MM-DD. Cannot be combined with from/to. */ date?: string; + /** @description Start: a park-local day (YYYY-MM-DD) or an RFC 3339 instant with an offset; rows are always whole days. from and to must be the same form. */ from?: string; + /** @description End: a day (inclusive) or an instant (exclusive). Defaults to today. Up to 3660 park-local days per call. */ to?: string; }; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -1183,16 +1311,20 @@ export interface operations { [name: string]: unknown; }; content: { - "application/json": components["schemas"]["HistoryErrorRateLimited"]; + "application/json": components["schemas"]["HistoryErrorRateLimited"] | components["schemas"]["RateLimited"]; }; }; }; }; getEntityLiveData: { parameters: { - query?: never; + query?: { + /** @description Only return entities of these types, comma-separated, e.g. ATTRACTION,SHOW. */ + entityType?: string; + }; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -1217,23 +1349,13 @@ export interface operations { "application/json": components["schemas"]["EntityNotFound"]; }; }; - /** @description Too Many Requests - Rate limit exceeded */ + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ 429: { headers: { [name: string]: unknown; }; content: { - "application/json": { - /** - * @description Error type - * @enum {string} - */ - error: "Rate limit exceeded"; - /** @description Rate limit exceeded message */ - message: string; - /** @description Time in seconds to wait before retrying */ - retryAfter?: number; - }; + "application/json": components["schemas"]["RateLimited"]; }; }; }; @@ -1243,6 +1365,7 @@ export interface operations { query?: never; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; }; cookie?: never; @@ -1267,23 +1390,13 @@ export interface operations { "application/json": components["schemas"]["EntityNotFound"]; }; }; - /** @description Too Many Requests - Rate limit exceeded */ + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ 429: { headers: { [name: string]: unknown; }; content: { - "application/json": { - /** - * @description Error type - * @enum {string} - */ - error: "Rate limit exceeded"; - /** @description Rate limit exceeded message */ - message: string; - /** @description Time in seconds to wait before retrying */ - retryAfter?: number; - }; + "application/json": components["schemas"]["RateLimited"]; }; }; }; @@ -1293,8 +1406,11 @@ export interface operations { query?: never; header?: never; path: { + /** @description The entity: its UUID, its slug, or for a destination its `externalId`. */ id: string; + /** @description A year from 1970 to 2150, e.g. 2026. */ year: string; + /** @description Month as two digits, 01 to 12. */ month: string; }; cookie?: never; @@ -1328,23 +1444,60 @@ export interface operations { "application/json": components["schemas"]["EntityNotFound"]; }; }; - /** @description Too Many Requests - Rate limit exceeded */ + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RateLimited"]; + }; + }; + }; + }; + getMe: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["V1Me"]; + }; + }; + /** @description Authentication failed */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["AuthenticationRequired"]; + }; + }; + /** @description Too many requests. Wait `retryAfter` seconds (also the Retry-After header). */ 429: { headers: { [name: string]: unknown; }; content: { - "application/json": { - /** - * @description Error type - * @enum {string} - */ - error: "Rate limit exceeded"; - /** @description Rate limit exceeded message */ - message: string; - /** @description Time in seconds to wait before retrying */ - retryAfter?: number; - }; + "application/json": components["schemas"]["RateLimited"]; + }; + }; + /** @description Response */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PlanUnavailable"]; }; }; };