Charter Boats
Charter Boats API
Fees

List Boat Fees

Get all fees for a specific boat

Showing API v1.1 — versionsShowing API v1.0 — versions

GET/boats/:id/fees

Retrieve the fees that apply to one stay on a boat, filtered by its active pricing source. Fees are ordered by sort_order.

You are reading API v1.1. Send api_version=1.1 to get it: a call with your API key, or to /api/ai/*, that names no version gets 1.0 — switch the picker at the top to v1.0 to read that shape.

You are reading API v1.0, what a call with your API key gets when it names no api_version. The rows are the same, without source. New integrations should send api_version=1.1 — see Versions.

Authentication

Send your API key in the X-API-Key header, as on every Operator API call. It reads only boats your company operates; another operator's boat is a 403 — sell those through the Discovery API. See Authentication.

Path Parameters

ParameterTypeDescription
idstringBoat ID (UUID)

Query Parameters

ParameterTypeRequiredDescription
startstringNoCharter start date (YYYY-MM-DD) -- selects the fees valid on that date
endstringNoCharter end date (YYYY-MM-DD). Only sets the charter length (see below), and only together with start; it does not filter validity
productstringNoRestrict to fees for a product variant (e.g. Bareboat, Crewed); fees with no product_name are always included. Without it the boat's default package is returned, never every package stacked
guestsintegerNoCrew size; selects the matching row of a per-person fee table (MMK boats — no other fee is narrowed by it). Defaults to the boat's capacity
rawbooleanNotrue returns EVERY fee row the boat's active source carries, scoped by nothing — the configuration reading, for an editor. The default (a quote) narrows by product, charter length and crew size, so exactly one row of a table survives; raw=true is the only way to see the whole table

When start is provided, only fees whose validity window contains the charter start date are returned — an operator publishes one price per window and a charter is priced by the window it departs in, so a stay crossing a boundary never gets two variants of one fee. Fees with no valid_from/valid_to dates are always included.

guests picks the row of a person-indexed fee table (some operators publish a park or permit fee per crew size). When absent, the boat's capacity is assumed.

Charter length

Operators often publish a fee as a table indexed by charter length -- one row per duration, such as a mooring fee of 60 EUR for 1 day, 42 EUR for 2 days and so on up to a weekly rate. Each row carries min_duration/max_duration, and only the row matching this charter contributes; the rest are omitted from the response.

The length is the stay's count in the boat's charter unit — its nights from start to end, or on a day-clock boat (check-out later in the day than check-in) its days, one more than the nights (see charter_unit on Resolve Pricing). When either is absent the standard charter week (7) is assumed, so a dateless call returns the fees a one-week booking would pay -- not every row of every table. Request a specific start/end to price any other duration.

Fees with no min_duration and no max_duration are unaffected and always returned.

The id path parameter must be a UUID: any other value is a 400 (Boat ID must be a UUID), and a UUID that names no boat is a 404 (Boat not found).

Request

curl https://charter.boats/api/boats/3a121be0-c1f8-4432-8e18-4a125b46da65/fees \
  -H "X-API-Key: YOUR_API_KEY"

For a specific stay, package and party size:

curl "https://charter.boats/api/boats/3a121be0-c1f8-4432-8e18-4a125b46da65/fees?start=2027-06-12&end=2027-06-19&product=Crewed&guests=6" \
  -H "X-API-Key: YOUR_API_KEY"

Response

Returns an array of fee objects.

[
  {
    "id": "f044b733-9d67-43c5-9280-4665d3569f63",
    "boat_id": "3a121be0-c1f8-4432-8e18-4a125b46da65",
    "description": "End cleaning Tranz log",
    "amount": 360,
    "period": "per_booking",
    "required": true,
    "sort_order": 0,
    "created_at": "2026-04-08T04:54:31.253295+00:00",
    "category": "service",
    "on_request": false,
    "valid_from": "1970-01-01",
    "valid_to": "2124-10-16",
    "min_duration": null,
    "max_duration": 365,
    "amount_is_percentage": false,
    "calculation_type": "separate_payment",
    "product_name": "Crewed"
  },
  {
    "id": "747f015b-c7fb-45fe-98ef-044468cd814b",
    "boat_id": "3a121be0-c1f8-4432-8e18-4a125b46da65",
    "description": "Skipper (+ food)",
    "amount": 170,
    "period": "per_day",
    "required": true,
    "sort_order": 0,
    "created_at": "2026-04-08T04:54:31.253295+00:00",
    "category": "service",
    "on_request": false,
    "valid_from": "1970-01-01",
    "valid_to": "2127-06-21",
    "min_duration": null,
    "max_duration": 365,
    "amount_is_percentage": false,
    "calculation_type": "separate_payment",
    "product_name": "Crewed"
  }
]

Response Fields

FieldTypeDescription
idstringFee ID (UUID)
boat_idstringBoat this fee belongs to
descriptionstringFee name/description
amountnumberFee amount in the boat's operator currency (or a percentage if amount_is_percentage is true — see Percentage fees)
periodstringBilling period (see below)
requiredbooleanIf true, fee is mandatory for every booking
categorystring | nullFee category (e.g. service, equipment)
on_requestbooleanIf true, fee must be requested separately
sort_orderintegerDisplay order
valid_fromstring | nullStart date of validity period (YYYY-MM-DD)
valid_tostring | nullEnd date of validity period (YYYY-MM-DD)
amount_is_percentagebooleanWhether amount is a percentage rather than a fixed value
percentage_basestring | nullOn a percentage fee, what the percentage is taken of, as Nausys names it — e.g. DAILY_PRICE (the per-day charter price), CLIENT_PRICE_WITH_EXTRAS_ADVANCE_PAYMENT and FINAL_CLIENT_PRICE (both: the charter price plus the other advance-paid extras). null means the charter price for the stay, which is what an MMK or operator-entered percentage always means. Some values name a figure we do not hold — see the callout under Percentage fees
calculation_typestring | nullHow the fee is settled: advance_payment is collected online with the charter payment; separate_payment is paid at the base; included_in_price is informational; null means the operator did not declare it and it is settled at the base. A REQUIRED advance_payment fee is money we move and are charged card fees on, so it carries the uplift in extras_processing_percent; one settled at the base does not
min_durationinteger | nullMinimum charter length for this fee to apply, compared with the stay's count in the boat's charter unit (nights, or days on a day-clock boat — see Charter length above)
max_durationinteger | nullMaximum charter length for this fee to apply, compared the same way
min_personsinteger | nullSmallest crew this fee applies to; null = any. The other half of the table rule above, in the crew-size dimension — guests picks the one row that matches
max_personsinteger | nullLargest crew this fee applies to; null = any
product_namestring | nullProduct/package variant this fee belongs to (e.g. Bareboat, Crewed)
sourcestring | nullv1.1 only. Where the row comes from — mmk, nausys or direct (null reads as direct); always the boat's active pricing source. A REQUIRED nausys advance_payment fee is collected online at Nausys's own figure even when its percentage base is one we cannot price
created_atstringISO 8601 timestamp

Fee Periods

PeriodDescription
per_bookingCharged once per booking
per_dayMultiplied by the stay's count in the boat's charter_unit — its nights, or its days (nights + 1) on a day-clock boat
per_personCharged per guest
per_person_per_dayPer guest, multiplied by the same count as per_day
per_person_per_nightPer guest per night
per_person_per_weekPer guest per started week
per_weekCharged per started week
one_wayOne-way delivery fee

Percentage fees

When amount_is_percentage is true, amount is a percentage of a base — the charter price for the whole stay unless percentage_base names another. It applies once to that base: the period does not multiply it by nights or weeks. A per_day fee of 10 with amount_is_percentage: true on a €1,400 week is €140, not €980.

Some percentage fees have no amount, only a rate — quote the rate.

  • A percentage_base of DEFINED_IN_CUSTOM or AGENCY_PRICE names a figure the operator sets and never publishes. PRICELIST_PRICE, PRICELIST_PRICE_WITHOUT_VAT and CLIENT_PRICE_WITHOUT_VAT name the list price, or a price net of VAT, and neither is the figure this API returns. Resolving any of them against the charter total invents a number: a 20% DEFINED_IN_CUSTOM fee on a €10,000 charter prints €2,000, indistinguishable on screen from a real charge.
  • A percentage on a per-person period has no honest reading either — it would multiply the whole charter's share by the crew (10% × 23 guests = 230% of the charter). Three such rows exist in the table and we bill none of them.

We state these as 20% beside the total and never inside it, and so should you. Corrected 2026-09-19; this example previously multiplied a percentage by the guest count.

The example on Resolve Pricing costs every period this way.

On this page