Search POIs (AI)
Find restaurants, fuel stations, shops, and attractions near a sailing destination
/ai/poisFind 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
| Parameter | Type | Required | Description |
|---|---|---|---|
location | string | No | Place 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_id | string | No | Exact location ID from a previous search_locations call. |
q | string | No | Direct POI-name search (no location required). Returns each POI with location: null. When q is sent, location and location_id are ignored. |
category | string | No | Filter by POI category (see below). Omit for all categories. |
limit | integer | No | Max results (default: 10, max: 30) |
At least one of location, location_id, or q is required.
Categories
| Value | Description |
|---|---|
restaurant | Restaurants, cafes, bars, pubs |
grocery | Supermarkets, convenience stores, bakeries, butchers |
fuel | Marine fuel and regular fuel stations |
chandlery | Boat supplies, marine equipment, yacht shops |
pharmacy | Pharmacies and chemists |
bank | Banks, ATMs, currency exchange |
laundry | Laundromats and dry cleaning |
entertainment | Attractions, museums, nightlife |
water | Drinking water access |
ice | Ice suppliers |
fishing | Fishing and bait shops |
provisioning | General ship stores |
parking | Car parks and street parking near the water |
medical | Hospitals, clinics, doctors, dentists |
worship | Churches, mosques, synagogues, temples |
other | Other useful places |
Request
Response
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
| Field | Type | Description |
|---|---|---|
pois | array | Points of interest — sorted by distance for a location search, unordered for a q search |
pois[].id | string | POI UUID |
pois[].name | string | POI name — the English form where we hold one; the POI's type when it has no name. Never null |
pois[].category | string | POI category |
pois[].subcategory | string|null | More specific category |
pois[].description | string|null | Description. May contain Markdown emphasis |
pois[].cuisine | string|null | Cuisine type (restaurants only) |
pois[].phone | string|null | Phone number |
pois[].website | string|null | Website URL |
pois[].opening_hours | string|null | Opening hours |
pois[].image_url | string|null | Image URL — often a third-party page's own image, hotlinked as found |
pois[].location | string|null | Distance + nearest searched marina (e.g. "65 meters from Sailing Club Mornar"). null for direct q searches. |
pois[].url | string | Link to the POI page on charter.boats |
locations_searched | array | Names of the marinas searched (omitted for q searches) |
categories_available | array | The 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_results | object | Present 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_unresolved | string | Present 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>". |
note | string | One-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
| Status | Message |
|---|---|
400 | Provide 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
/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
Response
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | POI UUID |
name | string | POI name — the English form where we hold one; the POI's type when it has no name |
category | string | POI category |
subcategory | string|null | More specific category |
description | string|null | Description, cut at 500 characters. May contain Markdown emphasis |
cuisine | string|null | Cuisine type (restaurants only) |
address | string|null | Street address |
city | string|null | City |
country | string|null | Country |
phone | string|null | Phone number |
website | string|null | Website URL |
opening_hours | string|null | Opening hours |
nearby_locations | array | Up to 3 nearby marinas with name, distance_meters, walking_time_minutes |
special_offers | array | Up to 3 offers with title, description, discount_type, discount_value |
url | string | Link to the POI page on charter.boats |
Errors
| Status | Message |
|---|---|
400 | Valid POI UUID required |
404 | POI not found |