# Royal Caribbean Scraper (`parsebird/royal-caribbean-scraper`) Actor

Scrape Royal Caribbean cruises: every sailing with ship, itinerary, ports with times, and per-cabin prices, discounts and category codes across 16 markets.

- **URL**: https://apify.com/parsebird/royal-caribbean-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.69 / 1,000 royal caribbean sailings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Royal Caribbean Scraper

Royal Caribbean Scraper extracts every cruise sailing from [royalcaribbean.com](https://www.royalcaribbean.com/cruises) — ship, itinerary, ports of call with arrival and departure times, and cabin prices with discounts and category codes — in 16 markets and their local currencies.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Filter by destination, departure port, ship, port of call, length, and sail dates, add senior, military, police/firefighter, or state-resident rates, and get one clean row per dated sailing with Interior, Ocean View, Balcony, and Suite prices side by side.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
Use the Apify actor "parsebird/royal-caribbean-scraper" to scrape Royal Caribbean cruise sailings and cabin prices. Call it with the apify-client package: client.actor("parsebird/royal-caribbean-scraper").call(run_input={"region": "USA", "maxRows": 200, "destinations": ["CARIB", "BAHAM"], "departurePorts": ["MIA", "FLL"]}), then read results from client.dataset(run["defaultDatasetId"]).iterate_items(). Inputs: region (required, one of USA, CAN, GBR, IRL, AUS, NZL, SGP, DEU, ITA, FRA, ESP, NLD, NOR, SWE, MEX, BRA; sets prices and currency), maxRows (integer 1-10000, default 500, one row per sailing), destinations (array of codes: ALCAN, FAR.E, AUSTL, BAHAM, BERMU, ATLCO, CARIB, EUROP, HAWAI, MEXCO, PACIF, T.PAN, ISLAN, SOPAC, T.ATL, TPACI), departurePorts (array of port codes such as MIA, FLL, PCN, GAL, SEA, BCN, ROM, STH, SYD, SIN), ships (array of two-letter ship codes such as IC, UT, WN, OA), portsOfCall (array of port codes the cruise must visit, e.g. PCC, NAS, CZM), minNights and maxNights (integers), sailDateFrom and sailDateTo (YYYY-MM-DD), sortBy (RECOMMENDED, PRICE_LOW_TO_HIGH, PRICE_HIGH_TO_LOW, SAIL_DATE, DURATION_LOW_TO_HIGH, DURATION_HIGH_TO_LOW), seniorRate, militaryRate, policeRate (booleans), residentState (two-letter US state), nameLanguage ("english" default or "local"), maxRequestRetries (default 5), minConcurrency (1), maxConcurrency (10), requestHandlerTimeoutSecs (30), useApifyProxy (default false), proxyUrl, apifyProxyGroups (default ["RESIDENTIAL"]), apifyProxyCountryCode. Each row is one sailing with sailingId, cruiseId, itineraryName, shipName, destinationCode/Name, departurePortCode/Name, arrivalPortCode/Name, sailDate, endDate, nights, portsOfCall, lowestPrice, currency, taxesAndFees, dynamic per-cabin fields price_{CUR}_{I|O|B|D}, originalPrice_*, discount_*, categoryCode_*, classification_*, roomTypeId_*, organized_pricing.tiers, rcSailingStatus, rcGroupId, rcHighlights, rcStateroomClasses, rcBookingLink, rcItineraryLink, rcPortsDetailedInfo (day, activity, port, arrivalTime, departureTime). Pricing: pay per sailing saved. API docs: https://apify.com/parsebird/royal-caribbean-scraper/api — get an API token at https://console.apify.com/settings/integrations
```

### What is Royal Caribbean Scraper?

**Royal Caribbean Scraper** is a **Royal Caribbean cruise data extractor and API alternative**. It reads the same cruise search that powers [royalcaribbean.com/cruises](https://www.royalcaribbean.com/cruises) and saves **every dated sailing** as a structured row: **ship, itinerary, departure and arrival ports, ports of call with times, and the price of each cabin class** — including the **original price, the discount, and the exact cabin category code** (like `ZI`, `N1`, `D1`, `SF`).

The easiest way to try it: open the **Input** tab, keep the United States market, and click **Start**. The example run saves 100 sailings in under a minute.

### What can Royal Caribbean Scraper do?

- 🌍 **16 markets, local prices** — United States, Canada, United Kingdom, Ireland, Australia, New Zealand, Singapore, Germany, Italy, France, Spain, Netherlands, Norway, Sweden, Mexico, and Brazil. Each market returns its own prices in its own currency (USD, CAD, GBP, EUR, AUD, NZD, SGD, NOK, SEK, MXN, BRL).
- 🛳️ **One row per sailing** — each dated departure is its own row with a unique `sailingId`, so a 7-night cruise that sails every Saturday gives you one row per Saturday. No duplicate rows.
- 💲 **Full cabin pricing** — Interior, Ocean View, Balcony, and Suite prices, the original (pre-discount) price, the discount amount, and the cabin category code, both as flat spreadsheet columns and as a nested `organized_pricing` object.
- 🎟️ **Special rates** — see prices with senior (55+), military, police and firefighter, or US state-resident rates applied, the same options Royal Caribbean offers on its cruise search.
- 🗺️ **Accurate itineraries** — ports of call, day by day, with arrival and departure times, embark/debark days, sea days, tendered stops, and cruisetour land days. Itineraries are read for **each sailing**, not copied from the first sailing of a cruise group, because dates of the same cruise can call at ports in a different order.
- 🧭 **Real arrival port** — the arrival port is the port where guests disembark, so one-way cruises such as transatlantic crossings show both ends (for example Barcelona → Fort Lauderdale).
- 🔤 **Consistent names across markets** — by default port and destination names are in English in every market, so "Athens (Piraeus)" in the US market is also "Athens (Piraeus)" in the German and Italian markets. Switch to the market's own language if you prefer. Port codes are always included.
- 🔎 **Filters** — destination, departure port, ship, port of call, number of nights, and sail-date range, plus Royal Caribbean's sort orders.

Because it runs on the Apify platform, you also get:

- **Scheduling** — run it daily or weekly with [Apify Schedules](https://docs.apify.com/platform/schedules) to track cruise price changes.
- **API access** — start runs and fetch results with the [Apify API](https://docs.apify.com/api/v2) or the Python and JavaScript clients.
- **Integrations** — send sailings to Google Sheets, Slack, Zapier, Make, n8n, or webhooks with [Apify integrations](https://docs.apify.com/platform/integrations).
- **Export formats** — download results as JSON, CSV, Excel, XML, or HTML.

### What data can you extract from Royal Caribbean?

| Field | Description |
|-------|-------------|
| `sailingId` | Unique sailing ID (package code + sail date), e.g. `IC07E479_2026-10-24` |
| `cruiseId` / `rcGroupId` | Royal Caribbean cruise group ID shared by all dates of the same cruise |
| `itineraryCode`, `itineraryName`, `cruiseType` | Package code, itinerary title, and `CRUISE` or `CRUISETOUR` |
| `shipCode`, `shipName` | Ship, e.g. `IC` / Icon of the Seas |
| `destinationCode`, `destinationName` | Royal Caribbean destination, e.g. `CARIB` / Caribbean |
| `departurePortCode`, `departurePortName`, `departurePortRegion` | Where the cruise starts |
| `arrivalPortCode`, `arrivalPortName`, `arrivalPortRegion` | Where guests disembark |
| `sailDate`, `startDate`, `endDate`, `nights`, `totalNights` | Dates and length (`totalNights` includes cruisetour land nights) |
| `portSequence`, `portsOfCall`, `portsOfCallCount` | Port code sequence and the list of ports visited |
| `lowestPrice`, `lowestPriceCabinCode`, `lowestPriceClassification` | Cheapest available cabin for this sailing |
| `currency`, `taxesAndFees`, `taxesAndFeesIncluded` | Market currency, taxes and fees, and whether prices include them |
| `price_{CUR}_{CODE}` | Current price of a cabin class, e.g. `price_USD_B` |
| `originalPrice_{CUR}_{CODE}`, `discount_{CUR}_{CODE}` | Price before the discount and the discount amount |
| `categoryCode_{CUR}_{CODE}` | Cabin category code behind the price, e.g. `ZI`, `4N`, `XB`, `WS` |
| `classification_{CUR}_{CODE}`, `roomTypeId_{CUR}_{CODE}` | Cabin super category (e.g. Balcony) and class ID (e.g. `BALCONY`) |
| `organized_pricing` | The same pricing as a list of tiers with `available` flags |
| `rateQualifiers` | Special rates applied to the prices (e.g. `senior:true`), or `null` |
| `rcSailingStatus` | Booking status of the sailing, e.g. `OPEN` |
| `rcHighlights` | Promotion badges, e.g. "Early Booking Bonus" |
| `rcStateroomClasses` | Cabin classes on the ship with amenities, max guests, and a photo |
| `rcPortsDetailedInfo` | Day-by-day ports with activity, arrival time, and departure time |
| `rcBookingLink`, `rcItineraryLink` | Booking page and itinerary page for this exact sailing |
| `imageUrl`, `scrapedAt` | Itinerary photo and the time the row was scraped |

Cabin class codes are `I` (Interior), `O` (Ocean View / Outside), `B` (Balcony), and `D` (Suite / Deluxe). Prices are the average per-person prices shown in Royal Caribbean's cruise search. A class with no price (`null`, `available: false`) is not bookable online for that sailing — usually sold out.

### How to scrape Royal Caribbean cruises

1. Open [Royal Caribbean Scraper](https://apify.com/parsebird/royal-caribbean-scraper) and go to the **Input** tab.
2. Pick a **Market** — this sets the prices and currency.
3. Optionally pick **Destinations**, **Departure ports**, **Ships**, or **Ports of call**.
4. Optionally set **Min/Max nights** and a **Sailing from / to** date range.
5. Optionally turn on **Special rates** (senior, military, police & firefighter, or state of residence).
6. Set **Max sailings** and click **Start**.
7. Download the sailings from the **Output** tab as JSON, CSV, or Excel, or fetch them through the API.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `region` | string | **Yes** | `USA` | Market: `USA`, `CAN`, `GBR`, `IRL`, `AUS`, `NZL`, `SGP`, `DEU`, `ITA`, `FRA`, `ESP`, `NLD`, `NOR`, `SWE`, `MEX`, `BRA` |
| `maxRows` | integer | No | `500` | Maximum sailings to save (1–10,000) |
| `destinations` | array | No | all | Destination codes (see below) |
| `departurePorts` | array | No | all | Departure port codes (see below) |
| `ships` | array | No | all | Two-letter ship codes, e.g. `IC`, `UT`, `WN`, `OA` |
| `portsOfCall` | array | No | — | Port codes the cruise must visit, e.g. `PCC`, `NAS`, `CZM` |
| `minNights` / `maxNights` | integer | No | — | Length of the sailing |
| `sailDateFrom` / `sailDateTo` | string | No | — | Departure date range, `YYYY-MM-DD` |
| `sortBy` | string | No | `RECOMMENDED` | `RECOMMENDED`, `PRICE_LOW_TO_HIGH`, `PRICE_HIGH_TO_LOW`, `SAIL_DATE`, `DURATION_LOW_TO_HIGH`, `DURATION_HIGH_TO_LOW` |
| `seniorRate` | boolean | No | `false` | Apply senior (55+) rates |
| `militaryRate` | boolean | No | `false` | Apply military rates |
| `policeRate` | boolean | No | `false` | Apply police and firefighter rates |
| `residentState` | string | No | — | Apply resident rates for a US state, e.g. `FL` |
| `nameLanguage` | string | No | `english` | `english` (same names in every market) or `local` |
| `maxRequestRetries` | integer | No | `5` | Retries for a failed request |
| `minConcurrency` | integer | No | `1` | Parallel requests to start with |
| `maxConcurrency` | integer | No | `10` | Maximum parallel requests |
| `requestHandlerTimeoutSecs` | integer | No | `30` | Timeout for one request, in seconds |
| `useApifyProxy` | boolean | No | `false` | Send requests through Apify Proxy |
| `proxyUrl` | string | No | — | Your own proxy URL (takes priority over Apify Proxy) |
| `apifyProxyGroups` | array | No | `["RESIDENTIAL"]` | Apify Proxy groups |
| `apifyProxyCountryCode` | string | No | matches market | Proxy country, e.g. `US`, `GB`, `AU` |

**Destination codes** (they mirror Royal Caribbean's own search filters):

| Code | Destination | Code | Destination |
|------|-------------|------|-------------|
| `ALCAN` | Alaska | `FAR.E` | Asia |
| `AUSTL` | Australia & New Zealand | `BAHAM` | Bahamas |
| `BERMU` | Bermuda | `ATLCO` | Canada & New England |
| `CARIB` | Caribbean | `EUROP` | Europe |
| `HAWAI` | Hawaii | `MEXCO` | Mexico |
| `PACIF` | Pacific Northwest | `T.PAN` | Panama Canal |
| `ISLAN` | Repositioning | `SOPAC` | South Pacific |
| `T.ATL` | Transatlantic | `TPACI` | Transpacific |

If you are moving from another tool that used `ALASK`, `ASIA`, `NORDI`, or `TRANS`, use `ALCAN`, `FAR.E`, `EUROP`, and `T.ATL`.

**Departure port codes:**

| Code | Port | Code | Port |
|------|------|------|------|
| `MIA` | Miami, FL | `FLL` | Fort Lauderdale, FL |
| `PCN` | Orlando (Port Canaveral), FL | `TPA` | Tampa, FL |
| `GAL` | Galveston, TX | `MSY` | New Orleans, LA |
| `SJU` | San Juan, Puerto Rico | `BYE` | Cape Liberty (New York), NJ |
| `BWI` | Baltimore, MD | `SEA` | Seattle, WA |
| `LAX` | Los Angeles, CA | `SAN` | San Diego, CA |
| `HNL` | Oahu (Honolulu), HI | `SWD` | Seward, AK |
| `YVR` | Vancouver, Canada | `STH` | Southampton, England |
| `BCN` | Barcelona, Spain | `ROM` | Rome (Civitavecchia), Italy |
| `BLQ` | Ravenna (Venice), Italy | `ATH` | Athens (Piraeus), Greece |
| `IST` | Istanbul, Turkey | `LIS` | Lisbon, Portugal |
| `CTG` | Cartagena, Colombia | `ONX` | Colón, Panama |
| `SYD` | Sydney, Australia | `BNE` | Brisbane, Australia |
| `SIN` | Singapore | `HKG` | Hong Kong |
| `BAO` | Shanghai (Baoshan), China | `YOK` | Tokyo (Yokohama), Japan |

Royal Caribbean's port line-up is seasonal, so a valid port can return no sailings in some months. An unknown code stops the run with a message listing the valid codes, instead of silently returning an empty dataset.

### Input examples

**Caribbean and Bahamas cruises from Miami and Fort Lauderdale:**

```json
{
    "region": "USA",
    "maxRows": 200,
    "destinations": ["CARIB", "EUROP", "BAHAM"],
    "departurePorts": ["MIA", "FLL"]
}
```

**Summer Europe cruises for the UK market, cheapest first:**

```json
{
    "region": "GBR",
    "destinations": ["EUROP"],
    "sailDateFrom": "2027-06-01",
    "sailDateTo": "2027-08-31",
    "sortBy": "PRICE_LOW_TO_HIGH"
}
```

**Senior rates for a Florida resident on Icon and Star of the Seas:**

```json
{
    "region": "USA",
    "ships": ["IC", "ST"],
    "seniorRate": true,
    "residentState": "FL"
}
```

**Every cruise that stops at Perfect Day at CocoCay, 3–5 nights:**

```json
{
    "region": "USA",
    "portsOfCall": ["PCC"],
    "minNights": 3,
    "maxNights": 5,
    "maxRows": 1000
}
```

### Output example

One row per sailing. Arrays are shortened here.

```json
{
    "sailingId": "IC07E479_2026-10-24",
    "cruiseId": "IC07MIA-2623281014",
    "itineraryCode": "IC07E479",
    "itineraryName": "Eastern Caribbean & Perfect Day",
    "cruiseType": "CRUISE",
    "shipCode": "IC",
    "shipName": "Icon of the Seas",
    "region": "USA",
    "currency": "USD",
    "destinationCode": "CARIB",
    "destinationName": "Caribbean",
    "departurePortCode": "MIA",
    "departurePortName": "Miami",
    "arrivalPortCode": "MIA",
    "arrivalPortName": "Miami",
    "sailDate": "2026-10-24",
    "endDate": "2026-10-31",
    "nights": 7,
    "portSequence": "MIA_SXM_STT_PCC_MIA",
    "portsOfCall": ["Philipsburg", "Charlotte Amalie", "Perfect Day CocoCay"],
    "lowestPrice": 1287.42,
    "lowestPriceClassification": "Interior",
    "taxesAndFees": 188.42,
    "taxesAndFeesIncluded": true,
    "price_USD_I": 1287.42,
    "originalPrice_USD_I": 1287.42,
    "discount_USD_I": 0,
    "categoryCode_USD_I": "ZI",
    "classification_USD_I": "Interior",
    "roomTypeId_USD_I": "INTERIOR",
    "price_USD_B": 2046.42,
    "originalPrice_USD_B": 3075.42,
    "discount_USD_B": 1029,
    "categoryCode_USD_B": "D1",
    "classification_USD_B": "Balcony",
    "roomTypeId_USD_B": "BALCONY",
    "organized_pricing": {
        "currency": "USD",
        "tiers": [
            {
                "code": "B",
                "roomTypeId": "BALCONY",
                "name": "Balcony",
                "classification": "Balcony",
                "categoryCode": "D1",
                "price": 2046.42,
                "originalPrice": 3075.42,
                "discountAmount": 1029,
                "taxesAndFees": 188.42,
                "available": true
            }
        ]
    },
    "rateQualifiers": null,
    "rcSailingStatus": "OPEN",
    "rcGroupId": "IC07MIA-2623281014",
    "rcHighlights": ["Last Minute Cruise Deals", "Early Booking Bonus", "President's Cruise"],
    "rcStateroomClasses": [
        {
            "id": "INTERIOR",
            "code": "I",
            "name": "Interior",
            "classification": "Interior",
            "maxCapacity": 4,
            "amenities": ["Our most budget-friendly option", "156 - 285 sq. ft. stateroom"]
        }
    ],
    "rcBookingLink": "https://www.royalcaribbean.com/booking/landing?groupId=IC07MIA-2623281014&sailDate=2026-10-24&shipCode=IC&packageCode=IC07E479&destinationCode=CARIB&selectedCurrencyCode=USD&country=USA",
    "rcItineraryLink": "https://www.royalcaribbean.com/cruises/itinerary/7-night-eastern-caribbean-perfect-day-from-miami-on-icon-IC07E479?sailDate=2026-10-24&packageCode=IC07E479&groupId=IC07MIA-2623281014&country=USA",
    "rcPortsDetailedInfo": [
        { "day": 1, "dayType": "PORT", "activity": "EMBARK", "portCode": "MIA", "portName": "Miami", "portRegion": "Florida", "arrivalTime": null, "departureTime": "16:30:00" },
        { "day": 2, "dayType": "CRUISING", "activity": "CRUISING", "portCode": "CRU", "portName": "Cruising", "portRegion": null, "arrivalTime": null, "departureTime": null }
    ],
    "scrapedAt": "2026-09-29T23:09:22+00:00"
}
```

### Use cases

- **Cruise price tracking** — schedule daily runs and follow price and discount changes per cabin class and sailing.
- **Travel agencies and cruise sellers** — keep an up-to-date catalog of Royal Caribbean sailings with booking links.
- **Deal alerts** — watch `discount_*` fields and `rcHighlights` badges and push new deals to Slack or email.
- **Market comparison** — run the same search in several markets and compare what each country pays for the same `sailingId`.
- **Special-rate analysis** — compare standard prices with senior, military, or resident rates for the same sailing.
- **Travel data products** — feed itineraries, ports, and prices into search tools, dashboards, or LLM apps.

### How it works

1. The actor builds a search from your filters, exactly like the filter panel on Royal Caribbean's cruise search page.
2. It reads the search results for the chosen market page by page, starting with a few requests in parallel and adding more while they succeed.
3. Each cruise group is split into its dated sailings, and each sailing gets its own itinerary, ports, and prices.
4. For markets that show local-language names, it looks up the English names by port code (unless you choose the market language).
5. Rows are saved to the dataset as they arrive, until `maxRows` is reached.

### How much does it cost to scrape Royal Caribbean?

Royal Caribbean Scraper uses pay-per-event pricing: you pay for each sailing saved to the dataset, and nothing for requests that return no sailings.

| Event | Free | Bronze | Silver | Gold |
|-------|------|--------|--------|------|
| Sailing scraped (per 1,000) | **$0.99** | **$0.89** | **$0.79** | **$0.69** |

A whole market is about 3,200 sailings, so a full United States catalog costs about $3.20 on the Free plan. The example run with 100 sailings costs about $0.10. You can set a maximum cost per run in the run options, and the actor stops when it is reached.

### Python and JavaScript API examples

**Python:**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("parsebird/royal-caribbean-scraper").call(run_input={
    "region": "USA",
    "destinations": ["ALCAN"],
    "departurePorts": ["SEA", "YVR"],
    "maxRows": 300,
})
for sailing in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(sailing["sailDate"], sailing["shipName"], sailing["lowestPrice"], sailing["currency"])
```

**JavaScript:**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('parsebird/royal-caribbean-scraper').call({
    region: 'AUS',
    destinations: ['SOPAC'],
    maxRows: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((s) => console.log(s.sailDate, s.itineraryName, s.price_AUD_B));
```

See the [API tab](https://apify.com/parsebird/royal-caribbean-scraper/api) for more clients and endpoints.

### FAQ

**Can it get agency-only rates such as group, interline, or corporate rate codes?**
No. Royal Caribbean Scraper collects the public consumer prices shown on royalcaribbean.com. It can apply the public special rates the website offers — senior, military, police and firefighter, and state resident — but not rates that need an agency or account login.

**Are prices per person?**
Yes. They are the average per-person prices Royal Caribbean shows in its cruise search. `taxesAndFeesIncluded` tells you whether taxes and fees are already included in the price, and `taxesAndFees` gives the amount.

**Why are some cabin prices empty?**
When Royal Caribbean has no price for a cabin class on a sailing, the price is `null` and `available` is `false` in `organized_pricing`. This usually means that class is sold out or not bookable online.

**Why do port names differ between markets?**
Royal Caribbean translates port and destination names in some markets (for example "Atene (Pireo)" in Italy). By default the actor returns the English names in every market so the same port has the same name everywhere. Set `nameLanguage` to `local` to keep the translated names. The port code (e.g. `ATH`) is always the same.

**What is the difference between `cruiseId` and `sailingId`?**
`cruiseId` is Royal Caribbean's cruise group — the same cruise on many dates. `sailingId` identifies one dated departure. Use `sailingId` as the unique key.

**How many sailings does Royal Caribbean have?**
About 940 cruise groups and 3,200 sailings per market when this actor was built. Set `maxRows` to 10,000 to get a whole market.

**Do I need a proxy?**
Usually not. Proxy is off by default. If requests get blocked, turn on `useApifyProxy`; the proxy country is matched to the market automatically, or you can set `apifyProxyCountryCode`. You can also use your own proxy with `proxyUrl`.

**Can I schedule runs and connect other tools?**
Yes. Use [Apify Schedules](https://docs.apify.com/platform/schedules) for recurring runs and [integrations](https://docs.apify.com/platform/integrations) for Google Sheets, Zapier, Make, n8n, Slack, or webhooks.

**Something is missing or broken?**
Open an issue in the **Issues** tab. We read every report and fix problems quickly.

### Is it legal to scrape Royal Caribbean?

Royal Caribbean Scraper only collects publicly available cruise and price information that anyone can see on royalcaribbean.com without logging in. It does not collect personal data. You should still check that your use of the data follows Royal Caribbean's terms and the laws that apply to you, such as GDPR in the EU. If you are unsure, ask a lawyer. Read more in Apify's blog post [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

### Other travel scrapers

- [CruiseMapper Scraper](https://apify.com/parsebird/cruisemapper-scraper) — cruise ships, itineraries, and schedules for many cruise lines
- [Ryanair Flight Scraper](https://apify.com/parsebird/ryanair-flight-scraper) — Ryanair flights, fares, and routes
- [Airbnb Scraper & API](https://apify.com/parsebird/airbnb-scraper) — Airbnb listings, prices, and hosts
- [Airbnb Availability Calendar Scraper](https://apify.com/parsebird/airbnb-availability-calendar-scraper) — Airbnb availability by date
- [Expedia Reviews Scraper](https://apify.com/parsebird/expedia-reviews-scraper) — Expedia hotel reviews
- [GetYourGuide Scraper](https://apify.com/parsebird/getyourguide-scraper) — tours and activities from GetYourGuide

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/royal-caribbean-scraper/changelog.md

# Actor input Schema

## `region` (type: `string`):

Choose the Royal Caribbean market. It sets the prices, currency, and booking links, the same as picking a country on royalcaribbean.com.

## `maxRows` (type: `integer`):

Set the maximum number of sailings (dated departures) to save. One row = one sailing. A whole market has about 3,200 sailings.

## `destinations` (type: `array`):

Pick destinations. Leave empty for all. Codes mirror Royal Caribbean's own search filters.

## `departurePorts` (type: `array`):

Pick home ports. Leave empty for all. Royal Caribbean's port line-up is seasonal, so a port can return no sailings.

## `ships` (type: `array`):

Pick ships. Leave empty for the whole fleet.

## `portsOfCall` (type: `array`):

Enter port codes the cruise must visit, e.g. <code>PCC</code> (Perfect Day at CocoCay), <code>NAS</code> (Nassau), <code>CZM</code> (Cozumel). Codes appear in the <code>portCode</code> field of <code>rcPortsDetailedInfo</code>.

## `minNights` (type: `integer`):

Only sailings of at least this many nights.

## `maxNights` (type: `integer`):

Only sailings of at most this many nights.

## `sailDateFrom` (type: `string`):

Only sailings departing on or after this date (YYYY-MM-DD).

## `sailDateTo` (type: `string`):

Only sailings departing on or before this date (YYYY-MM-DD).

## `sortBy` (type: `string`):

Order of cruise groups, as on Royal Caribbean's search page. Sailings of one cruise group stay together.

## `seniorRate` (type: `boolean`):

Show prices with senior (55+) rates applied, like ticking that box on Royal Caribbean's cruise search.

## `militaryRate` (type: `boolean`):

Show prices with military rates applied.

## `policeRate` (type: `boolean`):

Show prices with police and firefighter rates applied.

## `residentState` (type: `string`):

Show prices with resident rates for a US state, like the state-of-residence option on Royal Caribbean's US site.

## `nameLanguage` (type: `string`):

English keeps port and destination names identical in every market (e.g. 'Athens (Piraeus)'). Market language keeps the names Royal Caribbean shows in that market (e.g. 'Athen (Piräus)' in Germany). Port codes are always included.

## `maxRequestRetries` (type: `integer`):

Retries for a failed request.

## `minConcurrency` (type: `integer`):

Parallel requests to start with. Grows toward Max concurrency while requests succeed.

## `maxConcurrency` (type: `integer`):

Upper limit of parallel requests.

## `requestHandlerTimeoutSecs` (type: `integer`):

Timeout for one request.

## `useApifyProxy` (type: `boolean`):

Send requests through Apify Proxy. Not needed in most runs; turn it on if requests get blocked.

## `proxyUrl` (type: `string`):

Your own proxy, e.g. <code>http://user:pass@host:port</code>. Takes priority over Apify Proxy.

## `apifyProxyGroups` (type: `array`):

Apify Proxy groups used when Use Apify Proxy is on.

## `apifyProxyCountryCode` (type: `string`):

Two-letter proxy country (e.g. US, GB, AU). Leave empty to match the market automatically.

## Actor input object example

```json
{
  "region": "USA",
  "maxRows": 100,
  "destinations": [],
  "departurePorts": [],
  "ships": [],
  "portsOfCall": [],
  "sortBy": "RECOMMENDED",
  "seniorRate": false,
  "militaryRate": false,
  "policeRate": false,
  "nameLanguage": "english",
  "maxRequestRetries": 5,
  "minConcurrency": 1,
  "maxConcurrency": 10,
  "requestHandlerTimeoutSecs": 30,
  "useApifyProxy": false,
  "apifyProxyGroups": [
    "RESIDENTIAL"
  ]
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "region": "USA",
    "maxRows": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/royal-caribbean-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "region": "USA",
    "maxRows": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/royal-caribbean-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "region": "USA",
  "maxRows": 100
}' |
apify call parsebird/royal-caribbean-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/royal-caribbean-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4xbTKomf2R5arYe3X/builds/FFfgwYBsn4UEOTS5d/openapi.json
