Cruise Pricing API › API Reference

Cruise Pricing API Reference

Endpoints, request parameters and response schemas for cruise sailings, daily price history, price drops, cruise lines, ships and ports across 11 cruise lines. Overview, coverage and pricing tiers: https://www.track.cruises/en/data. Machine-readable spec: openapi.json. Subscribe via RapidAPI or directly (monthly or annual). What each plan may be used for: API terms.

GET /coverage

Data coverage per cruise line Public, no auth required. Returns per-line tracking start date, last update, market list, sailing and snapshot counts. Use it to validate data fit before subscribing. tracked_since and last_updated are live; total_sailings, total_snapshots and markets are recomputed once a day after the morning price collection.

GET https://cruise-pricing-api1.p.rapidapi.com/coverage

  • company (query) — Filter by cruise line. Call GET /cruise-lines for display names + per-line metadata.

GET /cruises

List cruises with filters Returns cruise sailings matching filters. Default sort: departure_date:asc. Freshness by plan: BASIC returns today's prices, capped at 10 rows per request. PRO prices run 7 days behind (as of freshness.data_as_of); on PRO, price filters and sort=price_euro|price_per_night_eur|updated_at return 403 tier_insufficient (they run on today's prices), and sailings first seen in the last 7 days are not listed yet. Once the PRO delay is on (freshness.delay_days: 7), price_per_night_eur is null, and a row with no snapshot near that date has null price/price_euro and price_delayed_missing: true. ULTRA and above: today's prices, every filter. Pagination: the response carries has_more and next_cursor; request the next page with starting_after=<next_cursor> and the same filters/sort. There is no cursor, page or offset parameter.

GET https://cruise-pricing-api1.p.rapidapi.com/cruises

  • limit (query) — Page size. Capped by plan: BASIC 10, PRO 100 (10 on /price-drops), ULTRA 500, MEGA 1,000. A higher limit is lowered to the cap (200 OK).
  • starting_after (query) — Opaque cursor from previous response's next_cursor.
  • sort (query) — Single-key sort. Allowed fields: departure_date, updated_at, price_euro, duration, price_per_night_eur. Direction defaults to asc. Default when omitted: departure_date:asc. sort=price_euro:asc returns the cheapest per-person fares first (rows without a fare are never listed); combine with min_duration/max_duration to rank one duration band per request. sort=duration lists only sailings with a known night count. sort=price_per_night_eur:asc returns the best value per person per night across all durations in one call; rows where it is null (fares we could not verify as bookable) are excluded from this sort but remain in the default listing. Use sort=updated_at:desc to surface the most-recently-scraped sailings first. Ties are broken deterministically; a next_cursor is only valid for the sort it was issued under. On PRO only departure_date and duration sorts are available; price and updated_at sorts return 403 tier_insufficient.
  • company (query) — Filter by cruise line. Call GET /cruise-lines for display names + per-line metadata.
  • locale (query) — Filter results to a single market. Determines pricing currency. Coverage varies by cruise line — call GET /coverage to see which lines support which locales.
  • departure_after (query) — Earliest departure date to include (yyyy-mm-dd, inclusive).
  • departure_before (query) — Latest departure date to include (yyyy-mm-dd, inclusive). Must not be earlier than departure_after.
  • min_duration (query) — Minimum cruise length in nights.
  • max_duration (query) — Maximum cruise length in nights. Must be >= min_duration when both are given.
  • min_price_eur (query) — Minimum per-person fare in EUR (price_euro, the cheapest cabin). Rows without a fare are excluded when this filter is set. Not available on PRO (403 tier_insufficient, required_tier: ultra).
  • max_price_eur (query) — Maximum per-person fare in EUR. Must be >= min_price_eur when both are given. Not available on PRO (403 tier_insufficient, required_tier: ultra).
  • min_price_per_night_eur (query) — Minimum per-person, per-night fare in EUR (price_euro / duration). Rows without a verified price_per_night_eur are excluded when this filter is set. Not available on PRO (403 tier_insufficient, required_tier: ultra).
  • max_price_per_night_eur (query) — Maximum per-person, per-night fare in EUR. Must be >= min_price_per_night_eur when both are given. Not available on PRO (403 tier_insufficient, required_tier: ultra).
  • ship (query) — Comma-separated ship names. Exact match, OR semantics.
  • port (query) — Port name(s) exactly as returned by /ports; OR semantics (the cruise touches ANY listed port). Repeat the key for several ports — ?port=Barcelona, Spain&port=Rome (Civitavecchia), Italy — each value is taken verbatim, so commas and parentheses inside a name are fine. A single port= value that is itself a /ports name counts as one name; any other single value keeps the legacy comma-separated form (port=Barcelona,Genoa → two names). At most 20 values. Since 2026-09-17; before that a name containing a comma matched nothing and a name with parentheses returned 503.
  • destination (query) — Destination label(s) as returned by /filter-options or /cruise-lines/{company}/destinations; OR semantics. Repeat the key for several destinations — ?destination=Caribbean&destination=Croatia, Greece & Italy — each value verbatim. A single value that is itself a catalog label counts as one label; any other single value keeps the legacy comma-separated form (destination=Caribbean,Mediterranean). At most 20 values.

GET /cruises/{id}

Single cruise detail One sailing in one market, with itinerary, per-cabin prices and (where the line publishes them) cabin_fare_details. Ids are unique per cruise line only, so pass company when the id could exist on several lines, and locale to pick the market; without locale the first market by locale code is returned. PRO: prices, currency and cabin_prices_per_person come from the newest snapshot at or before freshness.data_as_of (7 days ago; a sailing not re-priced since can be older); cabin_fare_details and price_per_night_eur are null. A sailing first seen in the last 7 days returns 404 cruise_not_found with the date PRO will show it.

GET https://cruise-pricing-api1.p.rapidapi.com/cruises/{id}

  • id (path, required) — Sailing id as returned by /cruises (cruise_id).
  • company (query) — Cruise line slug (e.g. princess, holland-america). Optional. Cruise ids are only unique per cruise line — Princess and Holland America share the same voyage-code format (e.g. Y731), so pass company to disambiguate those ids. When omitted and an id exists on several lines, the first line by slug is returned.
  • locale (query) — Market to return. Each sailing is stored once per market, each with its own currency and prices. Optional; when omitted, the first market by locale code is returned. Pass both company and locale when monitoring one sailing over time, so every call reads the same market. Also accepts the BCP-47 spelling (en-US). 404 when the sailing isn't sold in that market.

GET /cruises/{id}/price-history

Daily price history for a cruise PRO, ULTRA and MEGA. BASIC returns 403 tier_insufficient with required_tier: pro. On delayed PRO, a sailing first listed in the last 7 days returns 404. Sorted by date ASC (or newest first with order=desc). Pagination. Up to 2,000 snapshots per page. When has_more is true, pass next_cursor back as starting_after with the same filters and order. With cabin_type, a page can hold fewer than 2,000 snapshots (even none) and still have has_more: true: keep paging until next_cursor is null. Depth by tier. The Pro tier returns 90 days per cruise, ending at freshness.data_as_of (7 days ago) once the PRO delay is on (history_window.latest_date): from is clamped to history_window.earliest_date and the envelope carries history_window. Subscriptions started before 2026-10-07 keep the full archive on Pro. Ultra and Mega read the full archive back to each line's tracked-since date (see /coverage) and may use the bulk GET /price-history instead.

GET https://cruise-pricing-api1.p.rapidapi.com/cruises/{id}/price-history

  • id (path, required) — Sailing id as returned by /cruises (cruise_id).
  • from (query) — First snapshot date (yyyy-mm-dd, inclusive). On the Pro tier a date earlier than history_window.earliest_date is clamped to it.
  • to (query) — Last snapshot date (yyyy-mm-dd, inclusive). Default: today. On delayed PRO, snapshots after history_window.latest_date are never returned, whatever to says.
  • cabin_type (query) — Only return snapshots that have a price for this cabin type, and narrow cabin_prices_per_person to that cabin. Exact, case-sensitive cabin key as returned in cabin_prices_per_person (e.g. BALCONY, INTERIOR, HAVEN).
  • locale (query) — Filter results to a single market. Determines pricing currency. Coverage varies by cruise line — call GET /coverage to see which lines support which locales.
  • company (query) — Cruise line slug (e.g. princess, holland-america). Optional. Cruise ids are only unique per cruise line — Princess and Holland America share the same voyage-code format (e.g. Y731), so pass company to disambiguate those ids. Omitting it preserves the historical behavior.
  • starting_after (query) — Opaque cursor from previous response's next_cursor.
  • order (query) — asc (default) returns the oldest snapshot first; desc the newest first, so the first page holds the latest snapshots (up to 2,000; fewer with cabin_type).

GET /price-drops

Recent price drops Recent price drops sorted by drop_pct:desc (biggest drops first). A sailing is listed only when its price is a new 30-day low: at least 3% below the lowest price of the same cabin in that market over the previous 30 days (at least 7 days of prices). previous_price and drop_pct compare with the previous collected day. Drops are detected once a day per market after the morning price collection and surface for all tiers; BASIC: 10 rows a page. PRO, once the delay is on: the first 10 rows for your filters and sort, as of today (delay_days: 0, preview_of: ultra); has_more is false even when more drops exist, and starting_after returns 403 tier_insufficient. ULTRA and MEGA: the full list. Pagination: the response carries has_more and next_cursor; request the next page with starting_after=<next_cursor> and the same filters/sort. There is no cursor, page or offset parameter.

GET https://cruise-pricing-api1.p.rapidapi.com/price-drops

  • limit (query) — Page size. Capped by plan: BASIC 10, PRO 100 (10 on /price-drops), ULTRA 500, MEGA 1,000. A higher limit is lowered to the cap (200 OK).
  • starting_after (query) — Opaque cursor from previous response's next_cursor.
  • sort (query) — Single-key sort: drop_pct, detected_at or current_price_euro, each with :asc or :desc. Default drop_pct:desc. Direction defaults to desc for every field.
  • company (query) — Filter by cruise line. Call GET /cruise-lines for display names + per-line metadata.
  • locale (query) — Only drops in this market. Drops are computed per market, so one sailing can appear once per market, each with its own locale, currency and local prices. Also accepts the BCP-47 spelling (en-US).
  • min_drop_pct (query) — Only drops of at least this percentage (e.g. 10 for 10%). Non-negative number.
  • since (query) — Only drops detected on or after this date (yyyy-mm-dd, UTC). Poll with the date of your last run to pick up new drops.

GET /cruise-lines

All 11 cruise lines with metadata Sorted by cruise_count:desc. Use for buyer discovery UIs.

GET https://cruise-pricing-api1.p.rapidapi.com/cruise-lines

GET /cruise-lines/{company}

Single cruise-line detail One cruise line: display name, markets, destinations and ships we track for it.

GET https://cruise-pricing-api1.p.rapidapi.com/cruise-lines/{company}

  • company (path, required) — Cruise line slug, as listed by /cruise-lines.

GET /cruise-lines/{company}/destinations

Destinations for a cruise line Shortcut for filter UIs — returns just string[].

GET https://cruise-pricing-api1.p.rapidapi.com/cruise-lines/{company}/destinations

  • company (path, required) — Cruise line slug, as listed by /cruise-lines.

GET /filter-options

Valid filter values (companies, locales, destinations, ship names, ports) Use ?company=<slug> to scope values to one line.

GET https://cruise-pricing-api1.p.rapidapi.com/filter-options

  • company (query) — Filter by cruise line. Call GET /cruise-lines for display names + per-line metadata.

GET /ships

Ship catalog Ship catalog. Pagination: the response carries has_more and next_cursor; request the next page with starting_after=<next_cursor> and the same filters/sort. There is no cursor, page or offset parameter.

GET https://cruise-pricing-api1.p.rapidapi.com/ships

  • limit (query) — Page size. Capped by plan: BASIC 10, PRO 100 (10 on /price-drops), ULTRA 500, MEGA 1,000. A higher limit is lowered to the cap (200 OK).
  • starting_after (query) — Opaque cursor from previous response's next_cursor.
  • company (query) — Filter by cruise line. Call GET /cruise-lines for display names + per-line metadata.

GET /ports

Port catalog Port catalog. Pagination: the response carries has_more and next_cursor; request the next page with starting_after=<next_cursor> and the same filters/sort. There is no cursor, page or offset parameter. Names may contain commas and parentheses (Barcelona, Spain, Rome (Civitavecchia), Italy); pass them to /cruises?port= verbatim, one port= key per port. Sea days ("At Sea", "Fun Day At Sea", "Seetag", "Cruising"…) and cruise-line sea destinations (stops with sea_destination: true) are not ports and are not listed. Since 2026-10-17 they are also not accepted as port= values on /cruises.

GET https://cruise-pricing-api1.p.rapidapi.com/ports

  • limit (query) — Page size. Capped by plan: BASIC 10, PRO 100 (10 on /price-drops), ULTRA 500, MEGA 1,000. A higher limit is lowered to the cap (200 OK).
  • starting_after (query) — Opaque cursor from previous response's next_cursor.

GET /price-history

Bulk price history for a cruise line (Ultra / Mega) ULTRA / MEGA only. BASIC and PRO receive 403 tier_insufficient with required_tier: ultra. Always same-day prices. Every daily snapshot for one cruise line, optionally one market and/or one sailing, between from and to (inclusive, UTC dates; default: the last 30 days ending today). Ordered by recorded_at ASC. Page with starting_after=<next_cursor>; limit is capped at your tier's rows-per-request (Ultra 500, Mega 1000). A full line×market day is roughly 3,000–4,000 rows, so one line×market×year is about 1.2M rows ≈ 2,500 Ultra pages. Prefer this over one /cruises/{id}/price-history call per sailing when you want a whole line.

GET https://cruise-pricing-api1.p.rapidapi.com/price-history

  • company (query, required) — Cruise line slug. Required: each request reads one line.
  • locale (query) — Filter results to a single market. Determines pricing currency. Coverage varies by cruise line — call GET /coverage to see which lines support which locales.
  • cruise_id (query) — Restrict to one sailing (id as returned by /cruises).
  • from (query) — First snapshot date (inclusive, UTC). Default: to minus 30 days.
  • to (query) — Last snapshot date (inclusive, UTC). Default: today.
  • limit (query) — Rows per page, capped at the tier's rows-per-request.
  • starting_after (query) — next_cursor from the previous page. Issued by this endpoint only.

Cruise object fields

  • cruise_id
  • itinerary_id
  • title
  • company
  • locale
  • ship_name
  • departure_date
  • duration
  • price
  • price_euro
  • price_per_night_eur — price_euro / duration, rounded to 2 decimals. Per person, EUR, lowest available cabin. Null when price_euro or duration is unavailable, or when the fare failed a cross-market plausibility check (e.g. a promo-display teaser fare) -- such rows remain in the default listing but are excluded from sort=price_per_night_eur and the min/max_price_per_night_eur filters. Null on delayed PRO responses.
  • currency
  • cabin_prices_per_person — Per-cabin per-person pricing in the cruise's local currency. Keys are normalized cabin codes (INTERIOR, OCEANVIEW, BALCONY, MINISUITE, SUITE — plus line-specific tiers like CONCIERGE, AQUA, VISTA_SUITE, NEPTUNE_SUITE, HAVEN). Null when the underlying source didn't provide cabin-level pricing for this sailing. Only populated by GET /cruises/{id} — list endpoint GET /cruises omits this field to keep responses lean (call /cruises/{id} for the full breakdown). Costa exception: Costa's cabin-level pricing source has been unavailable since 2026-04-21, so this field is null for Costa sailings tracked after that date — lowest-price tracking (price, price_euro) is unaffected. On delayed PRO, the cabin prices of the snapshot served; null when price_delayed_missing.
  • cabin_fare_details — Per-cabin promotions and reference price for the fare in cabin_prices_per_person, as the cruise line advertised them on the snapshot date. Only populated by GET /cruises/{id}, for Norwegian (ncl), Royal Caribbean (royal-caribbean), Celebrity (celebrity-cruises) and Disney (disney-cruise-line); null for other lines and when nothing is known. offers is Norwegian only; the other lines provide reference_price_per_person. Keys are the same normalized cabin codes as cabin_prices_per_person; a cabin appears only when its details belong to exactly the price returned there. Describes what the line advertised with that fare, not a price anyone paid. Null on delayed PRO responses (offers and reference prices are same-day data).
  • destinations
  • ports_list — Itinerary stops in sailing order, from embarkation to disembarkation. Sea days are listed where the cruise line lists them. Two stops on the same day share a day number.
  • itinerary_url — Absolute URL of the cruise line's own page for this sailing (itinerary or booking page, the line's site for this market), or null when no link that opens this exact sailing is available. Never a relative path. Royal Caribbean and Celebrity links are the line's booking page for the sailing date; Costa links open the market site's sailing page.
  • updated_at — When this row's prices were collected. On a delayed PRO response, the time of the snapshot served (on or before freshness.data_as_of); null only on a delayed PRO row with no snapshot at all (price_delayed_missing: true).
  • price_delayed_missing — PRO only, present when true: no fare was observed for this sailing on or before freshness.data_as_of (/cruises searches the 4 days up to that date; /cruises/{id} searches all earlier history, so it can return a price where the list returned none), so price and price_euro (and on /cruises/{id} cabin_prices_per_person) are null, and currency / updated_at are those of the last observation, or null if there is none. Never filled with a newer price.