Charter Boats
Charter Boats API
Passages

Get Passage

Get full details for a specific sailing passage

Legacy — not maintained. Passages are a dormant data set generated in February 2026 and no longer updated. Many titles are generic ("Anchorage to Anchorage"), an embedded location name is often null, and some endpoints have since been merged into other locations without the geometry being recomputed. For passages boats were actually observed sailing, with measured times, use ais_passages on Get Location.

Endpoint

GET /passages/:slug

Description

Retrieve full details for a sailing passage, including route variants submitted by users, departure/arrival location details with images, and nearby POIs at each end.

Supports a direction parameter to view the return route (swaps departure and arrival). A passage is only served while both of its locations are published; otherwise it answers 404.

Authentication

Send X-API-Key: YOUR_API_KEY on every call from outside charter.boats — without it Cloudflare bot protection answers with an HTML 403 page, not JSON. Call it from your server: this route sends no CORS headers. See Authentication. Signed-in users of the site additionally see their own variant votes.

Path Parameters

ParameterTypeDescription
slugstringRoute slug (URL-friendly identifier)

Query Parameters

ParameterTypeRequiredDescription
directionstringNoSet to return to view the passage in reverse

Example Request

curl "https://charter.boats/api/passages/sivota-to-bay-svoyrna" \
  -H "X-API-Key: YOUR_API_KEY"

Return Direction

curl "https://charter.boats/api/passages/sivota-to-bay-svoyrna?direction=return" \
  -H "X-API-Key: YOUR_API_KEY"

Example Response

{
  "id": "ca6df91f-0984-4ce1-a43a-c2bb82d5cc52",
  "from_location_id": 21099,
  "to_location_id": 20010,
  "slug": "sivota-to-bay-svoyrna",
  "title": "Sivota to Bay Svoyrna",
  "description": null,
  "distance_nm": 3.3,
  "typical_duration_hours": null,
  "difficulty": null,
  "rating": null,
  "rating_count": 0,
  "variant_count": 1,
  "geojson": {
    "type": "Feature",
    "geometry": { "type": "LineString", "coordinates": [[20.6837174, 38.6219613], [20.7538605, 38.6263997]] },
    "properties": { "segments": 1, "waypoints": 2, "distance_km": 6.1, "distance_nm": 3.3, "fallback_segments": 1 }
  },
  "created_at": "2026-02-13T11:30:03.869677+00:00",
  "updated_at": "2026-02-13T11:30:04.002968+00:00",
  "from_location": {
    "id": 21099,
    "name": "Lefkas, Marina Sivota",
    "country": "Greece",
    "country_code": "gr",
    "lat": 38.623032,
    "lon": 20.682158,
    "harbour_category": "marina",
    "image_url": "https://www.marinareservation.com/timthumb.php?src=/upload/marina/191/Sivota_Marina_2.jpg&w=744&h=495"
  },
  "to_location": {
    "id": 20010,
    "name": "Bay Svoyrna",
    "country": "Greece",
    "country_code": "gr",
    "lat": 38.6263997,
    "lon": 20.7538605,
    "harbour_category": "bay",
    "image_url": null
  },
  "variants": [
    {
      "id": "ac854292-4625-4b0e-bdba-4d00f26c7bc1",
      "route_id": "ca6df91f-0984-4ce1-a43a-c2bb82d5cc52",
      "user_id": null,
      "name": "Default route",
      "description": null,
      "geojson": { "type": "Feature", "geometry": { "type": "LineString", "coordinates": [] } },
      "waypoints": null,
      "distance_nm": 3.3,
      "min_draft_m": null,
      "notes": null,
      "upvote_count": 0,
      "downvote_count": 0,
      "source": "searoute",
      "is_default": true,
      "created_at": "2026-02-13T11:30:04.002968+00:00",
      "user": null
    }
  ],
  "user_votes": {},
  "from_pois": [
    {
      "distance_meters": 46,
      "poi": {
        "id": "487cadd1-263b-4f75-95eb-2d97d8ad0158",
        "name": null,
        "category": "grocery",
        "subcategory": "supermarket"
      }
    },
    {
      "distance_meters": 96,
      "poi": {
        "id": "78a1303c-33c8-4b5f-a5fd-34a45a4d057b",
        "name": "Pirates",
        "category": "restaurant",
        "subcategory": "pub"
      }
    }
  ],
  "to_pois": [
    {
      "distance_meters": 2830,
      "poi": {
        "id": "751aa314-d89b-41b1-9c3b-4e45be70804d",
        "name": "Il Paradiso",
        "category": "restaurant",
        "subcategory": "restaurant"
      }
    }
  ],
  "is_reversed": false
}

Response Fields

FieldTypeDescription
idstringRoute ID (UUID)
from_location_id / to_location_idnumberDeparture / arrival location IDs
slugstringURL slug
titlestringRoute title
descriptionstring|nullRoute description
distance_nmnumber|nullDistance in nautical miles
difficultystring|nullDifficulty level
typical_duration_hoursnumber|nullEstimated sailing time
ratingnumber|nullAverage rating
rating_countnumberNumber of ratings
variant_countnumber|nullNumber of route variants
geojsonobject|nullDefault route geometry as a GeoJSON Feature (geometry + properties)
created_at / updated_atstringRow timestamps
from_locationobjectDeparture location: id, name (stored name — can be null), country, country_code, lat, lon, harbour_category, image_url
to_locationobjectArrival location (same shape)
variantsarrayRoute variants sorted by default first, then by votes
variants[].name / .descriptionstring|nullVariant label and notes
variants[].geojsonobjectVariant geometry (GeoJSON Feature)
variants[].distance_nmnumber|nullVariant distance
variants[].min_draft_mnumber|nullMinimum draft for the variant
variants[].sourcestring|nullHow the variant was generated (e.g. searoute)
variants[].is_defaultbooleanWhether this is the default route
variants[].user_idstring|nullAuthor user ID (null for system-generated variants)
variants[].userobject|nullAuthor summary (id, name); null for system-generated variants
variants[].upvote_countnumberNumber of upvotes
variants[].downvote_countnumberNumber of downvotes
user_votesobjectAuthenticated user's votes (variant_id to vote mapping: 1 = up, -1 = down). Empty if not logged in.
from_poisarrayUp to 5 nearest active POIs at departure: distance_meters + nested poi { id, name, category, subcategory }. POIs carry no rating. poi.name is the stored name and can be null for an unnamed car park, shop or pharmacy — label it from category/subcategory
to_poisarrayUp to 5 nearest active POIs at arrival (same shape)
is_reversedbooleantrue when direction=return was used

Notes

  • When direction=return is set, from_location and to_location are swapped, along with from_pois and to_pois. from_location_id / to_location_id, geojson and variants are not swapped — they still describe the stored direction.
  • user_votes is only populated for authenticated users. Each key is a variant ID, and the value is 1 (upvote) or -1 (downvote).

Error Responses

404 Not Found

{
  "statusCode": 404,
  "message": "Route not found"
}

Returned for an unknown slug, and for a passage whose departure or arrival location is not published.

On this page