Charter Boats
Charter Boats API
Agent API

Agent Search

Dense agent search revealing platform, deeplinks, per-week availability and options

Same in API v1.0 and v1.1

GET/agent/boats

The dense "one boat per line" agent feed. It reuses the same matching and value-ordering as the consumer search, then re-fetches each match with agent-only columns and enriches it for the requested week.

Authentication

Logged-in session as an active agent. Returns 401 when not logged in, 403 when the session has no active agent profile. See the Agent API overview.

Query Parameters

Accepts the same parameters as the consumer search (GET /api/boats). All are optional; with none, it returns the value-ranked default set.

ParameterTypeDescription
location_idintegerLocation to search (marina/city/region resolved server-side).
location_type + location_valuestringAlternative to location_id — e.g. location_type=text&location_value=Lefkada. Named sailing regions (Dalmatia, the Dodecanese) resolve too. A value that matches no known place returns an empty result set rather than boats from elsewhere.
country_codestringNarrows a location_type of state, city or municipality to one country (e.g. GR). Ignored for country, text and location_id.
typestringBoat type(s), comma-separated: sailboat, catamaran, yacht, motorboat, gulet, rib.
dstringCharter dates as YYYY-MM-DD,YYYY-MM-DD (Saturday→Saturday). A dated row is priced for the stay asked — the boat page's own Total for those nights (from the boat's changeover day when it does not take the dates asked, at its minimum stay when that is longer). A single date does not reliably availability-filter — always pass a range.
guestsintegerMinimum capacity — only boats with capacity ≥ guests match. A dated row is priced for this many guests (at most the boat's capacity); without it, at max guests.
priceMin / priceMaxnumberDaily-rate bounds (EUR).
cabins / berths / toiletsintegerMinimum counts; cabins counts guest cabins (crew cabins are not counted).
lengthMin / lengthMaxnumberLength bounds (feet).
yearMin / yearMaxintegerBuild-year bounds.
rentalTypesstringComma-separated: bareboat, skippered, no_licence_needed. no_licence_needed means the operator asks no licence of the charterer — it does not mean a skipper comes with the boat.
featuresstringComma-separated equipment slugs.
manufacturerSlugstringManufacturer filter.
makesstringComma-separated make/model filter: bali (whole make) or bali:4.2 (one model). Same semantics as GET /api/boats. Use this — not q — to search by model.
qstringBoat NAME filter — matched against the boat's title only, never its model, and as a WHOLE WORD (Bella matches Bella Luna, never Marbella). For a make or model, use makes.
sort or sortBystringrecommended (default, best value first), price-low, price-high, rating (aliases price_asc / price_desc accepted).
limitintegerResults to return. Default 20, max 50.
offsetintegerNumber of results to skip.

Request

# Requires an authenticated agent session (cookie); an API key does not authenticate here.
curl "https://charter.boats/api/agent/boats?location_id=11336&d=2026-10-03,2026-10-10&guests=6" \
  -H "Cookie: <charter.boats session cookie>"

Response

{
  "boats": [
    {
      "id": "3a121be0-c1f8-4432-8e18-4a125b46da65",
      "slug": "beneteau-oceanis-40",
      "title": "Škuribanda",
      "model": "Oceanis 40",
      "boat_type": "sailboat",
      "year": 2006,
      "capacity": 8,
      "cabins": 3,
      "berths": 8,
      "heads": 2,
      "length_ft": 39.2,
      "average_rating": null,
      "review_count": 0,
      "hero_image_url": "https://media.charter.boats/boats/3a121be0-c1f8-4432-8e18-4a125b46da65/images/<image-id>_hero.jpg",
      "images": [
        "https://media.charter.boats/boats/3a121be0-c1f8-4432-8e18-4a125b46da65/images/<image-id>_hero.jpg",
        "https://media.charter.boats/boats/3a121be0-c1f8-4432-8e18-4a125b46da65/images/<image-id>_hero.jpg"
      ],
      "series": [
        { "w": 0, "start": "2026-09-05", "per_day": 0, "avail": false, "option": false, "booked": true },
        { "w": 1, "start": "2026-09-12", "per_day": 600, "avail": true, "option": true, "booked": false }
      ],
      "manufacturer": { "id": "…", "name": "Beneteau", "slug": "beneteau", "logo_url": null },
      "brand": "Beneteau",
      "location": { "id": 11336, "name": "D-Marin Lefkas", "city": "Lefkada", "country": "Greece", "country_code": "GR" },
      "currency": "EUR",
      "features": [{ "label": "Bimini", "slug": "bimini" }, { "label": "Autopilot", "slug": "autopilot" }, { "label": "Bow thruster", "slug": "bow_thruster" }],
      "platform": "nausys",
      "rank": 0.31,
      "similar": false,
      "price": {
        "per_day": 492,
        "weeks": 1,
        "nights": 7,
        "week_start": null,
        "rental": "bareboat"
      },
      "week": {
        "index": 4,
        "available": true
      },
      "list_price": { "per_day": 492, "total": 3440, "original_per_day": null, "discount_pct": null, "from": false, "week": 4, "week_start": "2026-10-03", "units": 7, "unit": "night", "party": 6, "label": "for 7 nights · all fees in", "deposits": 2000 },
      "price_summary": "3440 EUR total for the week of Oct 3–10, 6 guests.",
      "list_split": { "due_now": 3140, "paid_at_pickup": 300, "total": 3440, "original_due_now": null, "discount_pct": null },
      "detail_dates": "2026-10-03,2026-10-10",
      "links": {
        "mmk": null,
        "nausys": "https://agency.nausys.com/NauSYS-agency/app/yachtReservations.xhtml"
      },
      "booked_12m_pct": 52,
      "options": [
        { "start": "2026-10-17", "end": "2026-10-24", "expires": "2026-09-20" }
      ],
      "activity": { "option": false, "booked": false, "last_option_at": null }
    }
  ],
  "total": 42,
  "agent": { "split_percent": <your split>, "commission_gated": false }
}

When no d week is passed, price.per_day is the boat's lowest list figure (list_price.from is true), price.weeks/price.nights are null, week.index is -1, and week.available is null.

The response carries no pagination cursor (hasMore / next_offset): page with offset + limit against total.

Response Fields

FieldTypeDescription
boats[].idstringBoat UUID
boats[].slugstring|nullURL slug
boats[].titlestringBoat name (falls back to model when the boat has no valid name)
boats[].modelstring|nullModel name
boats[].brandstring|nullManufacturer name
boats[].manufacturerobject|null{ id, name, slug, logo_url }
boats[].boat_typestringType of boat
boats[].year / capacity / cabins / berths / heads / length_ftnumber|nullSpecs. length_ft is length overall (LOA).
boats[].crew_cabinsnumber|nullCrew cabins, not counted in cabins, which counts guest cabins as the cabins filter does.
boats[].average_rating / review_countnumber|nullGuest review summary
boats[].locationobject{ id, name, city, country, country_code }
boats[].currencystringCurrency code (operator's base currency, default EUR)
boats[].hero_image_urlstring|nullThe boat's hero image, 1200×800 variant on media.charter.boats
boats[].imagesstring[]Up to 5 gallery images, ordered with the same category-diverse logic as the boat detail hero. Served as the 1200×800 WebP variant on media.charter.boats — hotlink these directly; the un-resized original is not a public URL.
boats[].seriesobject[]Forward price/availability series for the graph: one entry per week from the current week, up to 26 weeks (fewer near the end of the 52-week window). { w, start, per_day, avail, option, booked } — w week index, start that week's start date on this boat's own changeover day, per_day that week's list figure, the grand total at max guests per day for the boat (0 = not sold that week, never free), avail free in the availability calendar, option / booked whether a hold or a booking covers it.
boats[].featuresobject[]Equipment & amenities: { label, slug } — label is the display spelling matching the detail page, slug the canonical filterable feature (or null for non-canonical items). Kit standard on the boat's model is included even when the operator did not list it, as on the detail page
boats[].platformstringAgent-only. Source pricing platform: mmk, nausys, or direct. Marks the price-of-record deeplink.
boats[].ranknumber|nullValue rank used by recommended ordering (lower = better value; null when the boat has no bookable priced week)
boats[].unpricedbooleantrue for a published boat we hold no prices for. A search with no dates and no price filter lists these after the priced ones (2026-09-21) — they are real matches, counted in total, but price.per_day is 0 and nothing about them can be quoted. The response also carries unpriced_start_index (where they begin) and lists_unpriced (whether this search admits them at all); bookable_as_searched is false on every one.
boats[].priceobjectHeadline price — the row's LIST figure: per_day = list_price.per_day, the grand total (charter less the auto discount, every required fee charged now or at pickup, the 45 EUR platform fee; deposits never) per day for the boat — dated, the boat page's Total for the stay and guests asked ÷ its days; dateless, the lowest week at max guests; weeks (the span searched in weeks) / nights (the length the figure covers, in charter_unit; null without a date), charter_unit (day on a boat whose check-out is later in the day than its check-in; night otherwise), rental (bareboat / skippered / skipper optional / skipper required (paid extra)). When the boat cannot be sold in the requested week the figure comes from the nearest week it can be sold in among the weeks it was matched on, and week_start carries that week's start on this boat's own changeover day; it is also set when the boat page would not take the dates asked for and the row is priced for the boat's own week. Removed 2026-10-01: amount and unit (a stay total or a day rate — a published name keeps its meaning, so the new figure has a new key), required_extras, required_extras_unit, required_extras_from (the fees are inside the figure). Removed 2026-10-02: discount_pct and payment_terms — a list row carries the list figure only; the stay's own prices are the detail's (see detail_dates).
boats[].weekobjectSelected-week detail: index (the requested week in the rolling 52-week window), available (whether that requested week is free). Removed 2026-10-02: discount_pct. Removed 2026-10-01: all_in, price_per_day, charter_total, required_extras, required_extras_from, platform_fee (a second figure beside the list figure). index=-1 / available=null when no week is set.
boats[].list_priceobject|nullThe row's one figure and its words: per_day (= price.per_day), total, original_per_day, discount_pct, from, week, week_start, units, unit, party (the guests priced: guests, else max guests), label — the same object /api/ai/boats rows carry.
boats[].price_summarystring|nullAdded 2026-10-02: the same stay in the words Mermaid and /api/ai/boats use — "T EUR total for the week of Oct 3–10, N guests[. P% discount applied.]", any other stay its dates and length "T EUR total for Oct 3–6 (3 nights), N guests. …" (dateless "From T EUR total a week, …"). null where list_price is.
boats[].list_splitobject|nullThe collapsed row's Due now / Paid at pickup / Total for the stay list_price covers — dated, the boat page's own quote for that stay and party; dateless, the "from" week at max guests: due_now (= total − paid_at_pickup + the deposits charged online), paid_at_pickup (the required non-deposit fees paid at the base), total (the grand total, deposits never in it), original_due_now (Due now with the partner discount undone and no coupon) and discount_pct (derived from the two, null under 1%). null where the week is unpriced or not yet baked with the split. For the complete price of a stay — due now, paid at pickup, the total and the deposits — use the boat page or /api/ai/boats/{id} with dates.
boats[].detail_datesstring|nullYYYY-MM-DD,YYYY-MM-DD — the stay the row's DETAIL is priced for: the exact stay the row is quoted for (dated), or the week its "from" figure came from (dateless); null when there is nothing to quote. The list row carries no other price (since 2026-10-02 — deposit and commission_preview are removed): for the stay's due now, paid at pickup, total and deposits call GET /api/ai/boats/{id}?date_from=…&date_to=… (stay_price), and for your commission estimate GET /api/agent/commission-estimate?boat=<id>&start=YYYY-MM-DD&end=YYYY-MM-DD[&guests=N] → { estimate } (null when the page would not sell the stay; 403 for anyone but an active agent).
boats[].linksobjectAgent-only. { mmk, nausys } deeplinks (a platform key is null when the boat isn't on it).
boats[].similarbooleantrue for nearby/flexible backfill boats appended after the strict matches — the UI groups these under a "Similar boats" divider
boats[].booked_12m_pctnumberShare of the next 52 weeks covered by a blocking event that is not an option — partner bookings, and owner/calendar blocks too
boats[].optionsarrayHolds over the next 12 months, soonest first, at most 8: { start, end, expires } (expires may be null)
boats[].activityobject{ option, booked, last_option_at } — option / booked describe the selected week (false when no week is set); last_option_at is when the most recent hold on this boat was placed, across the next 12 months
totalintegerTotal boats matching the filters (before limit); similar backfill boats are not counted
agentobjectThe calling agent's { split_percent, commission_gated } — split_percent is your own configured split, set on your agent profile; it is not a standard rate. commission_gated is always false since 2026-10-01.

On this page