Open dataset

Scheduled ferry crossings with operator-published fares

Version 1.0.0 · CC BY 4.0 · Read 12 September 2026

Every scheduled departure we could observe on 2,190 directed port pairs, with the ship that sails it and the price its operator was charging on the day it was read.

What is in it

Counted from the same snapshot the files are built from, so this table and the CSVs cannot drift apart.

  • 2,190Directed port pairs
  • 895Pairs with an observed sailing
  • 1,295Pairs asked about with nothing sailing
  • 2,948Sailing rows
  • 2,709Distinct operator trip identifiers
  • 5,997Individual fare quotes
  • 120Operators
  • 357Named vessels
  • 65Countries
  • 600Ports used by a crossing
  • 299Of those, carrying a UN/LOCODE
  • 1,440Ports in the register

Sailings were looked for on 17 September 2026, 21 September 2026, 25 September 2026, 29 September 2026. A pair with nothing sailing means no ship answered on those four dates.

Sailing rows by the country of the ports at either end. The inventory is Mediterranean and Western European.

Where the ships are
  • Italy1,175
  • Greece910
  • Spain274
  • Croatia184
  • Indonesia149
  • Singapore126
  • United Kingdom105
  • Türkiye77

Top 8 countries by sailing rows. Bars are relative to the largest.

How it was built

  • Ask the graph where ships goEach port in the register is asked, by its exact name, which ports it has direct connections to. Asking by code returns the wrong port: the code Barcelona itself uses answers with a port in Croatia. The port the service answers for is checked against the port asked about, and a substitution is discarded.
  • Ask each pair for real departuresEvery pair the graph named is asked for trips on four dates spread across the bookable window. Ferry inventory opens roughly two to three weeks ahead, and each pair keeps the earliest date that answered.
  • Write down what came backDeparture, arrival, operator, vessel and every quoted accommodation price are recorded as returned, in integer minor units. Nothing is normalised onto a house vocabulary, nothing is averaged, and nothing is filled in. Company names are kept as published even where two spellings are plainly one company.
  • Join, compute, and label what was computedPorts are matched to settlements for coordinates, distances are computed, counts are counted. Each of those is marked at the column level, so a reader can see exactly which numbers came from an operator and which came from us.

How each row is evidenced

Every row in every file carries source, source_url, fetched_at and evidence.

measured
Read from an operator-published response about a specific service: a named ship, a departure time, a price the operator is charging. 3,963 rows.
filed
Read from a published register or connections graph, as the operator or the aggregator declares it. 2,735 rows.
derived
Computed by the build script from the two above. No row is evidenced this way: computed values sit in columns, and every resource names them.

A measured row can still carry a computed column, so each file has derived_columns: a distance, a duration, a slug, a count and the currency label. The fare amounts are not in it.

The upstream price field carries no currency code. Ferryhopper quotes in euro and these files record EUR, so fare_currency is listed as derived: the three letters are ours, the amounts are the operator’s.

Real rows

Eight sailings from sailings.csv, one per operator, in the order the file holds them. Open the file and you will find these.

CrossingDepartureOperatorVesselDurationCheapest quote
AG.MARINA (AEGINA)PIRAEUS17 Sept 2026, 11:20HELLENIC SEAWAYSAERO HIGHSPEED0h 30mEUR 19.50
AG.MARINA (AEGINA)PIRAEUS17 Sept 2026, 18:35MAGIC SEA FERRIESMAGIC 20h 30mEUR 19.50
AGAETESANTA CRUZ DE TENERIFE17 Sept 2026, 06:00FRED OLSENBAÑADEROS EXPRESS1h 20mEUR 50.60
AGROPOLIPALINURO17 Sept 2026, 09:05TRAVELMARTRAVELMAR2h 55mEUR 15.50
AJACCIOMARSEILLE17 Sept 2026, 18:00LA MERIDIONALEPIANA13h 00mEUR 39.00
AJACCIOPORTO TORRES17 Sept 2026, 07:15CORSICA FERRIESCORSICA FERRIES4h 15mEUR 26.00
ALCUDIABARCELONA17 Sept 2026, 09:45BALEARIAMARGARITA SALAS3h 30mEUR 111.50
ALGECIRASCEUTA17 Sept 2026, 07:30DFDS IBERIACEUTA JET1h 00mEUR 38.50

Times are the clock times the operator published, shown exactly as they came. Fares are the cheapest accommodation class quoted on that sailing.

Download

A Frictionless Data Package: a descriptor, a Table Schema for each resource, CSV in RFC 4180, and a SHA-256 for every file. Nothing here needs an account or a key.

FileRowsSizeSHA-256
crossings.csv2,190797 KiB01fcb5104a0aadaf9b7e46b033906a9871dd13c435a82e368547a5426c09de3c
sailings.csv2,9481.2 MiB6a94303ef626b529a3f9a424affd08e235bf2af883765d80412a91ea56a8519e
operators.csv12030 KiB13433a3c272d3546ac8889e629d4a28f9e3fffc25e5b8f17a0e7abe6c72867b1
ports.csv1,440332 KiBc65482c9c4d1cb9e039d43e656724343082b016a6741b06c86e0a97ebe5e242d
datapackage.json4 KiBa05cfbe9dab053fee119842b4cfee0e56b386214709c3ddb37ae6bb623534170
checksums.txt171 KiB6f207fcf03f6dc98d880861429ad60f619e36342dfc20fce7a335a467d0ad814
README.md14 KiBe6546a7f951e16a2228e45e76fc016911e23c91886c417a073a597870ac5b199

The whole package also lives in the repository at data-packages/ferry-crossings, and node tools/data/ferry-package.mjs rebuilds it from the committed snapshot. It is deterministic, so a diff is a data change and nothing else.

Cite this

Attribution is the licence condition and the only thing we ask. Either form below is fine.

Formatted

Orlero (2026). Scheduled ferry crossings with operator-published fares (Version 1.0.0) [Data set]. https://orlero.com/data/ferry-crossings

BibTeX

@dataset{orlero_ferry_crossings_1_0_0,
  author    = {{Orlero}},
  title     = {{Scheduled ferry crossings with operator-published fares}},
  year      = {2026},
  version   = {1.0.0},
  publisher = {Orlero},
  url       = {https://orlero.com/data/ferry-crossings},
  note      = {CC BY 4.0}
}

Identifier

No DOI yet. Cite the URL and version above.

Licence

CC BY 4.0. Share it, adapt it, sell something built on it, and credit it. Version 4.0 covers the EU sui generis database right on the same terms. Vessel, company and port names are the marks of their owners and are reproduced as facts about who runs what.

https://creativecommons.org/licenses/by/4.0/

What it does not tell you

  • A snapshot, not a feed. A fare is what the operator published at the moment it was read.
  • An empty crossing is not proof of no service: four probed dates can miss a weekly sailing.
  • Coordinates are settlement centroids, not berths. Athens resolves to Piraeus and Rome to Civitavecchia, so a computed distance is between towns and is a lower bound on the sailed track.
  • UN/LOCODEs are assigned by shape, not looked up. A code counts as one when it is five characters and its country prefix agrees with the register. Join on the raw operator code if you need certified codes.
  • GTFS and Parquet are left to a later release, because four probed dates do not support a service calendar.
  • The timestamps are local clock times stamped as UTC, recorded exactly as published, and the port file carries an IANA zone to resolve them. It affects the 390 sailings whose two ports sit in different zones.
  • 0 sailings have no duration: their published arrival is not after their published departure, so both timestamps stay as published and the computed column is empty.
Plan with Ori

Ori, the trip planner

Ask it something like this