Discounts
List, create, change and end your company's discount codes
Same in API v1.0 and v1.1
/dashboard/discounts?company_id=POST/dashboard/discountsPATCH/dashboard/discounts/:idDELETE/dashboard/discounts/:idYour company's discounts: codes a guest enters, and the pay-in-full discount. A discount belongs to a company and applies to all its boats or to the boats you name.
Authentication
Requires one of:
- API key:
X-API-Keyheader with your API key. This is the way to call it from your own systems. - Session: a signed-in charter.boats session — what the dashboard uses from the browser. Outside charter.boats a request without a key is stopped by bot protection (HTML
403), so integrations should use the key.
Either way, the account must be a member of the company. Your company's id is the company_id on any boat List Your Fleet returns.
List discounts
GET /dashboard/discounts?company_id=<id> answers the company's active discounts, newest first. Each carries the fields below plus created_by_name, and — when it is aimed at named boats — boat_ids.
Create a discount
POST /dashboard/discounts
| Field | Type | Required | Description |
|---|---|---|---|
company_id | string | Yes | Your company |
trigger | string | No | code (default) — the guest's code; pay_in_full — taken off when the guest pays everything at once |
code | string | For code | The code, stored in capitals. Must be unique. A pay-in-full discount gets one made for it |
discount_type | string | Yes | percentage or fixed. Pay-in-full is percentage only |
discount_value | number | Yes | Above 0. A percentage is at most 100, a pay-in-full one at most 20 |
currency | string | No | Default EUR |
auto_apply | boolean | No | Default true: applied without the guest typing the code. A pay-in-full discount is always applied |
all_boats | boolean | No | Default true. false with boat_ids aims it at those boats |
boat_ids | array | No | Boat UUIDs, with all_boats: false |
start_date / end_date | string | No | The dates it can be booked between (YYYY-MM-DD); either side may be left open |
stay_from / stay_to | string | No | The check-in dates it covers; either side may be left open |
description | string | No | A description of the discount |
max_uses | integer | No | How many times it may be used. Empty for no limit |
A company has one active pay-in-full discount at a time. The response is the created discount.
Change a discount
PATCH /dashboard/discounts/:id — send any field of the table above except company_id and trigger, or is_active. boat_ids replaces the named boats when sent with all_boats: false; all_boats: true clears them. A pay-in-full discount keeps its generated code and stays applied automatically. A sent discount_type or discount_value is held to the same rules as on create, checked against the discount as it would stand after the change: a discount_value sent alone must still fit the stored type (at most 100 for a percentage, 20 for pay-in-full), and switching to percentage checks the stored value. The response is the discount.
End a discount
DELETE /dashboard/discounts/:id switches the discount off (is_active: false) and answers { "success": true }.
Errors
| Status | Message |
|---|---|
400 | company_id is required |
400 | company_id, discount_type, and discount_value are required |
400 | code is required for code coupons |
400 | discount_type must be percentage or fixed |
400 | Pay-in-full discounts must be percentage type / Pay-in-full discount is capped at 20% |
400 | Percentage discount cannot exceed 100% / Discount value must be positive |
400 | Coupon ID required |
401 | Invalid API key — a key that belongs to no account |
401 | Invalid API key format — a malformed key |
401 | Authentication required — no key and no signed-in session |
403 | Not a company member |
404 | Coupon not found |
409 | A coupon with this code already exists |
409 | An active pay-in-full discount already exists for this company. … |
500 | Failed to fetch coupons / Failed to create coupon / Failed to update coupon / Failed to deactivate coupon |