List Boat Fees
Get all fees for a specific boat
Showing API v1.1 — versionsShowing API v1.0 — versions
/boats/:id/feesRetrieve 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
| Parameter | Type | Description |
|---|---|---|
id | string | Boat ID (UUID) |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start | string | No | Charter start date (YYYY-MM-DD) -- selects the fees valid on that date |
end | string | No | Charter end date (YYYY-MM-DD). Only sets the charter length (see below), and only together with start; it does not filter validity |
product | string | No | Restrict 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 |
guests | integer | No | Crew 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 |
raw | boolean | No | true 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
For a specific stay, package and party size:
Response
Returns an array of fee objects.
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Fee ID (UUID) |
boat_id | string | Boat this fee belongs to |
description | string | Fee name/description |
amount | number | Fee amount in the boat's operator currency (or a percentage if amount_is_percentage is true — see Percentage fees) |
period | string | Billing period (see below) |
required | boolean | If true, fee is mandatory for every booking |
category | string | null | Fee category (e.g. service, equipment) |
on_request | boolean | If true, fee must be requested separately |
sort_order | integer | Display order |
valid_from | string | null | Start date of validity period (YYYY-MM-DD) |
valid_to | string | null | End date of validity period (YYYY-MM-DD) |
amount_is_percentage | boolean | Whether amount is a percentage rather than a fixed value |
percentage_base | string | null | On 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_type | string | null | How 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_duration | integer | null | Minimum 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_duration | integer | null | Maximum charter length for this fee to apply, compared the same way |
min_persons | integer | null | Smallest 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_persons | integer | null | Largest crew this fee applies to; null = any |
product_name | string | null | Product/package variant this fee belongs to (e.g. Bareboat, Crewed) |
source | string | null | v1.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_at | string | ISO 8601 timestamp |
Fee Periods
| Period | Description |
|---|---|
per_booking | Charged once per booking |
per_day | Multiplied by the stay's count in the boat's charter_unit — its nights, or its days (nights + 1) on a day-clock boat |
per_person | Charged per guest |
per_person_per_day | Per guest, multiplied by the same count as per_day |
per_person_per_night | Per guest per night |
per_person_per_week | Per guest per started week |
per_week | Charged per started week |
one_way | One-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_baseofDEFINED_IN_CUSTOMorAGENCY_PRICEnames a figure the operator sets and never publishes.PRICELIST_PRICE,PRICELIST_PRICE_WITHOUT_VATandCLIENT_PRICE_WITHOUT_VATname 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_CUSTOMfee on a €10,000 charter prints €2,000, indistinguishable on screen from a real charge. - A percentage on a per-person
periodhas 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.