Charter Boats API
Pricing

Seasonal Pricing

Manage seasonal pricing for boats

GET/boats/:id/prices

Retrieve all seasonal pricing rules for a boat, ordered by priority (highest first), then by start month.

Path Parameters

ParameterTypeDescription
idstringBoat ID (UUID)

Request

curl https://charter.boats/api/boats/550e8400-e29b-41d4-a716-446655440000/prices

Response

Returns an array of price objects.

[
  {
    "id": "a1b2c3d4-...",
    "boat_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Peak Price",
    "start_month": 6,
    "start_day": 1,
    "end_month": 8,
    "end_day": 31,
    "price_per_day": 500,
    "priority": 1,
    "source": "direct",
    "source_id": null,
    "original_price_per_day": null,
    "discount_percentage": null,
    "discount_name": null,
    "valid_from_year": null,
    "valid_to_year": null,
    "created_at": "2024-01-15T10:00:00Z"
  },
  {
    "id": "e5f6a7b8-...",
    "boat_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Off Price",
    "start_month": 11,
    "start_day": 1,
    "end_month": 3,
    "end_day": 31,
    "price_per_day": 300,
    "priority": 0,
    "source": "direct",
    "source_id": null,
    "original_price_per_day": null,
    "discount_percentage": null,
    "discount_name": null,
    "valid_from_year": null,
    "valid_to_year": null,
    "created_at": "2024-01-15T10:00:00Z"
  }
]

Response Fields

FieldTypeDescription
idstringPrice ID (UUID)
boat_idstringBoat this price belongs to
namestringPrice name
start_monthintegerStart month (1-12)
start_dayintegerStart day (1-31)
end_monthintegerEnd month (1-12)
end_dayintegerEnd day (1-31)
price_per_daynumberDaily rate for this price
priorityintegerHigher priority wins on overlaps (default: 0)
sourcestringPricing source (direct, nausys, or mmk)
source_idstring | nullExternal source identifier
original_price_per_daynumber | nullPre-discount price (if a discount applies)
discount_percentagenumber | nullActive discount percentage
discount_namestring | nullName of the discount
valid_from_yearinteger | nullYear the price starts applying
valid_to_yearinteger | nullYear the price stops applying
created_atstringISO 8601 timestamp

Prices can wrap around year boundaries (e.g., November 15 to January 15).


Create Price

POST/boats/:id/prices

Create a new seasonal pricing rule. Requires authentication as a company member for the boat.

Authentication

X-API-Key: cb_live_xxxxx

Request Body

FieldTypeRequiredDescription
namestringYesPrice name (e.g., "Peak Price")
start_monthintegerYesStart month (1-12)
start_dayintegerYesStart day (1-31)
end_monthintegerYesEnd month (1-12)
end_dayintegerYesEnd day (1-31)
price_per_daynumberYesDaily rate for this price
priorityintegerNoHigher priority wins on overlaps (default: 0)

Request

curl -X POST https://charter.boats/api/boats/550e8400-e29b-41d4-a716-446655440000/prices \
  -H "Content-Type: application/json" \
  -H "X-API-Key: cb_live_xxxxx" \
  -d '{
    "name": "Holiday Price",
    "start_month": 12,
    "start_day": 20,
    "end_month": 1,
    "end_day": 5,
    "price_per_day": 600,
    "priority": 2
  }'

Response

Returns the created price object.

{
  "id": "c3d4e5f6-...",
  "boat_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Holiday Price",
  "start_month": 12,
  "start_day": 20,
  "end_month": 1,
  "end_day": 5,
  "price_per_day": 600,
  "priority": 2,
  "source": "direct",
  "source_id": null,
  "original_price_per_day": null,
  "discount_percentage": null,
  "discount_name": null,
  "valid_from_year": null,
  "valid_to_year": null,
  "created_at": "2024-01-20T14:30:00Z"
}

Errors

StatusMessage
400Name, start/end dates, and price are required
400Month must be between 1 and 12
400Day must be between 1 and 31
404Boat not found

Price Resolution

When multiple prices overlap, the one with the highest priority value wins. If no price covers a date, the date is considered unavailable.

Priority order:

  1. Date-specific overrides (highest)
  2. Seasonal pricing (by priority)
  3. No coverage = unavailable

On this page