Resolve Pricing
Get the resolved price for each day in a date range
/boats/:id/pricingResolve the effective daily price for each day in a date range. Each day is matched against the boat's seasonal pricing rules. Days with no season coverage come back with no price. This is a pricing lookup, not an availability check -- see the note under Response Fields.
Only sellable seasons take part: those of the boat's active pricing source (pricing_source on Get Boat — a boat listed on two platforms is priced from the one it is booked through), excluding quotes we can't sell (one-way delivery legs, weeks quoted from another base, implausible partner-side prices).
Authentication
Send your API key in the X-API-Key header, as on every Operator API call — see Authentication.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Boat ID (UUID). A slug is not accepted |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start | string | Yes | Start date (YYYY-MM-DD) |
end | string | Yes | End date (YYYY-MM-DD) |
product | string | No | Price one product variant (e.g. Bareboat, Crewed — see mmk_products on Get Boat). Seasons with no product stay in play. Without it, the seasons of every product compete for each day under the rules below, so pass it whenever the boat sells more than one package |
The range is exclusive of the end date (i.e., start up to but not including end).
Request
Response
Response Fields
prices array
| Field | Type | Description |
|---|---|---|
date | string | Date (YYYY-MM-DD) |
price | number | Resolved price for this day; 0 when no season covers it (isPriced: false) |
source | string | Always season |
seasonName | string | Name of the matching season (only present for priced days) |
isPriced | boolean | A season covers this date, so it has a price. Not an availability check -- see the note below |
originalPrice | number | null | Pre-discount price (if a seasonal discount applies) |
discountPercentage | number | null | Active discount percentage |
discountName | string | null | Name of the discount |
summary object
| Field | Type | Description |
|---|---|---|
totalDays | integer | Total days in the range |
pricedDays | integer | Number of days a season covers |
unpricedDays | integer | Number of days no season covers |
subtotal | number | Sum of prices for priced days |
minPrice | number | Lowest daily price among priced days |
maxPrice | number | Highest daily price among priced days |
avgPrice | number | Average daily price among priced days |
This endpoint does not check availability. It reads seasonal pricing only --
it never looks at bookings, blocks or synced calendar events, so a fully booked
week still comes back with every day priced. To find out whether a boat is free,
call GET /api/boats/availability and treat its
blockedDates as nights: the checkout day is handed back in the morning and is
never occupied.
Renamed on 2026-08-05 from isAvailable / availableDays / unavailableDays,
which read as an availability check and were used as one.
Price Sources
- season: The day is priced by a seasonal pricing rule. The matching season's name is included in
seasonName.
Pricing Waterfall
- Season -- a matching season sets the price for the day. Where several seasons cover
the same day, they are resolved in this order:
- The day's own week. A season that starts on the week-start the day falls in,
counted in 7-day steps from the request's
start, wins. Partner feeds return one quote per bookable week, so a boat with two changeover days has two overlapping seasons across almost every night; this picks the one quoted for the week the day actually sits in. A 14-day range therefore takes days 8-14 from week two's own season, not week one's. - Priority -- higher
prioritywins. - Narrower range -- on equal priority, the season covering fewer days wins, since a week-scoped quote is a fresher figure than the season-wide one it overlaps.
- The day's own week. A season that starts on the week-start the day falls in,
counted in 7-day steps from the request's
- No coverage -- if no season covers the day it has no price (
isPriced: false,price: 0, noseasonName)
Step 1.1 only breaks ties between seasons that already cover the day -- it never stretches a season or invents a price. A range longer than its own week's season falls through to the remaining rules for the days outside it.
Errors
| Status | Message |
|---|---|
400 | Boat ID must be a UUID |
400 | start and end dates are required |
400 | Dates must be in YYYY-MM-DD format |
404 | Boat not found |
500 | Failed to fetch seasons |
An id that is not UUID-shaped — a slug, for instance — answers 400 without touching the database; a well-formed UUID no boat carries answers 404. Both used to be 500 with Boat not found in the message, so an integration written before 2026-09-15 that keys on the message keeps working.
Use Cases
Calculate Booking Total
Price the stay, then add the required fees. Fees are costed per stay the way charter.boats costs them — a percentage fee applies once, to its base for the whole stay, multiplied only by guests — and they split into what is paid online with the booking and what is settled at the base.
Fees settled at the base (separate_payment, or no calculation_type) are real costs of the charter but are not part of the online payment. Confirm the dates are free with Boat Availability before presenting a total — this endpoint prices booked weeks too.