Charter Boats
Charter Boats API
AI Integrations

Search POIs (AI)

Find restaurants, fuel stations, shops, and attractions near a sailing destination

GET/ai/pois

Find points of interest near a sailing destination. Accepts a location name (fuzzy matched), a location ID from a previous search, or a direct POI-name query. A location search returns POIs sorted by distance from the nearest searched marina; a name search (q) returns name matches in no particular order.

POIs carry no ratings. There is no rating or rating_count field on any POI response, and there is no rating filter on any POI endpoint. The ratings we used to hold were read off Google's knowledge panel for a fuzzy text query with no name or identity check, and were wrong at scale — nine unrelated bank branches all reported the same 3.9M reviews. Rank POIs by category and distance instead. Locations, routes and itineraries do carry real ratings.

Authentication

No authentication required. A key is optional — a valid API key records the call against your account; an invalid one is ignored, never a 401. All /ai/* endpoints share one rate-limit budget: 60 requests per 10 minutes (30 for Custom GPT clients); past it you get 429 with a Retry-After header.

Query Parameters

ParameterTypeRequiredDescription
locationstringNoPlace name, resolved by the same resolver as boat search (marina, city, island, sailing region or country — a trailing country or region is understood, as in Nydri, Greece). POIs are hub-and-spoke, so the place and its immediate neighbours are searched together, up to 25 locations; locations_searched names them. Use this, location_id, or q.
location_idstringNoExact location ID from a previous search_locations call.
qstringNoDirect POI-name search (no location required). Returns each POI with location: null. When q is sent, location and location_id are ignored.
categorystringNoFilter by POI category (see below). Omit for all categories.
limitintegerNoMax results (default: 10, max: 30)

At least one of location, location_id, or q is required.

Categories

ValueDescription
restaurantRestaurants, cafes, bars, pubs
grocerySupermarkets, convenience stores, bakeries, butchers
fuelMarine fuel and regular fuel stations
chandleryBoat supplies, marine equipment, yacht shops
pharmacyPharmacies and chemists
bankBanks, ATMs, currency exchange
laundryLaundromats and dry cleaning
entertainmentAttractions, museums, nightlife
waterDrinking water access
iceIce suppliers
fishingFishing and bait shops
provisioningGeneral ship stores
parkingCar parks and street parking near the water
medicalHospitals, clinics, doctors, dentists
worshipChurches, mosques, synagogues, temples
otherOther useful places

Request

# Find restaurants near Split (by name)
curl "https://charter.boats/api/ai/pois?location=split&category=restaurant&limit=2"
 
# Find all POIs near a specific location ID
curl "https://charter.boats/api/ai/pois?location_id=12908&limit=20"
 
# Direct POI name search
curl "https://charter.boats/api/ai/pois?q=Nava"

Response

{
  "pois": [
    {
      "id": "33cd84e7-fb62-4639-b689-067df56b32bb",
      "name": "Velum",
      "category": "restaurant",
      "subcategory": "restaurant",
      "description": "Velum sits right on the waterfront at Uvala Baluni and serves up **fresh seafood and Mediterranean dishes** from breakfast through dinner...",
      "cuisine": null,
      "phone": null,
      "website": null,
      "opening_hours": null,
      "image_url": "https://media-cdn.tripadvisor.com/media/photo-m/1280/1d/0f/de/64/restaurant.jpg",
      "location": "65 meters from Sailing Club Mornar",
      "url": "https://charter.boats/pois/33cd84e7-fb62-4639-b689-067df56b32bb"
    },
    {
      "id": "262b3a18-f20e-443d-88b3-d3ee46ad15f6",
      "name": "King of the Sea",
      "category": "restaurant",
      "subcategory": "restaurant",
      "description": "Tucked away at **Marina Spinut**, Re di Mare is one of Split's best-kept seafood secrets...",
      "cuisine": null,
      "phone": "+38521386789",
      "website": "https://www.redimare.com/",
      "opening_hours": null,
      "image_url": "https://visiting-split.com/wp-content/uploads/2016/04/naslovna3-e1445270721297.jpg",
      "location": "78 meters from Split Marina Lučica",
      "url": "https://charter.boats/pois/262b3a18-f20e-443d-88b3-d3ee46ad15f6"
    }
  ],
  "locations_searched": [
    "Nautika centar Nava", "Split West Coast Marina", "Sportska lučica Mornar", "Sailing Club Mornar",
    "ACI Marina Split", "Split Marina Lučica", "Split MCI Marine Club International",
    "Vranjic, Split", "Marina Spinut, Split", "Marina Zenta, Split"
  ],
  "categories_available": ["restaurant"]
}

Names come back in English where we hold an English form — the second POI above is Re di Mare locally — and a POI with no name of its own shows its type instead ("Pharmacy", "Street Parking"). Descriptions may contain Markdown emphasis (**…**, *…*).

When using q (direct name search), each POI has location: null and the response omits locations_searched.

Response Fields

FieldTypeDescription
poisarrayPoints of interest — sorted by distance for a location search, unordered for a q search
pois[].idstringPOI UUID
pois[].namestringPOI name — the English form where we hold one; the POI's type when it has no name. Never null
pois[].categorystringPOI category
pois[].subcategorystring|nullMore specific category
pois[].descriptionstring|nullDescription. May contain Markdown emphasis
pois[].cuisinestring|nullCuisine type (restaurants only)
pois[].phonestring|nullPhone number
pois[].websitestring|nullWebsite URL
pois[].opening_hoursstring|nullOpening hours
pois[].image_urlstring|nullImage URL — often a third-party page's own image, hotlinked as found
pois[].locationstring|nullDistance + nearest searched marina (e.g. "65 meters from Sailing Club Mornar"). null for direct q searches.
pois[].urlstringLink to the POI page on charter.boats
locations_searchedarrayNames of the marinas searched (omitted for q searches)
categories_availablearrayThe categories among the POIs returned in this response, most frequent first — not every category the place has. With category set it holds only that one. For the full set at a place, read poi_categories on /ai/locations/{id}
no_resultsobjectPresent only when pois is empty. { searched, why, try_next[] } — what was actually searched after resolution, which constraint emptied it, and the concrete calls to try next.
location_unresolvedstringPresent when the location (or location_id) you sent matched no location we hold. Echoes the term that failed — for an id, as "location_id <n>".
notestringOne-sentence rendering of no_results, generated from it so the two can never disagree.

Empty results

An empty pois array is always explained — it never comes back bare. A place name that matches nothing returns 200 with no_results and location_unresolved naming the term that failed, not an error: "we could not find that place" and "that place has no POIs of this kind" are different answers and want different retries. Resolve the name with search_locations and call again with the location_id it gives you.

Errors

StatusMessage
400Provide location, location_id, or q (search by name) — returned only when none of the three was sent. A location that was sent but did not resolve is a 200 with location_unresolved, not a 400.

POI Details

GET/ai/pois/{id}

Full detail for a single point of interest, including address, nearby marinas with walking times, and any special offers. The {id} must be a POI UUID.

Request

curl "https://charter.boats/api/ai/pois/297cb8af-90cd-4acc-ad6a-28325cb105c8"

Response

{
  "id": "297cb8af-90cd-4acc-ad6a-28325cb105c8",
  "name": "Nava Nautical Center",
  "category": "chandlery",
  "subcategory": "boat_shop",
  "description": "If you're serious about buying a yacht in Croatia, this is the place — Nautika Centar Nava has been in the game **since 1990** and is an authorized dealer for big names like Lagoon, Beneteau, X-Yachts, and Nimbus...",
  "cuisine": null,
  "address": null,
  "city": null,
  "country": null,
  "phone": null,
  "website": "https://www.navaboats.com/",
  "opening_hours": null,
  "nearby_locations": [
    { "name": "Split, West Coast (Zapadna obala)", "distance_meters": 101, "walking_time_minutes": 2 },
    { "name": "Nautika centar Nava", "distance_meters": 205, "walking_time_minutes": 3 },
    { "name": "ACI Marina Split", "distance_meters": 231, "walking_time_minutes": 3 }
  ],
  "special_offers": [],
  "url": "https://charter.boats/pois/297cb8af-90cd-4acc-ad6a-28325cb105c8"
}

Response Fields

FieldTypeDescription
idstringPOI UUID
namestringPOI name — the English form where we hold one; the POI's type when it has no name
categorystringPOI category
subcategorystring|nullMore specific category
descriptionstring|nullDescription, cut at 500 characters. May contain Markdown emphasis
cuisinestring|nullCuisine type (restaurants only)
addressstring|nullStreet address
citystring|nullCity
countrystring|nullCountry
phonestring|nullPhone number
websitestring|nullWebsite URL
opening_hoursstring|nullOpening hours
nearby_locationsarrayUp to 3 nearby marinas with name, distance_meters, walking_time_minutes
special_offersarrayUp to 3 offers with title, description, discount_type, discount_value
urlstringLink to the POI page on charter.boats

Errors

StatusMessage
400Valid POI UUID required
404POI not found

On this page