Contents
On this page
Create Quote - Plugixa Boat Rental
POST /pbr/v1/quote
The full price of a booking that has not been made yet, line by line, priced exactly as a booking with the same choices would be. Nothing is written.
Public: no key or login is needed. It is the booking widget’s own route.
Note. Do not send an API key:
/quoteis not on a key’s list, so a request carrying one is refused403 plugixa_boatrental_key_scope. A quote also does not check that a boat is free or that the marina is open: that is answered when the booking is made. It is rate limited per visitor address: 240 requests every 10 minutes.
Request
POST https://your-site.example/wp-json/pbr/v1/quote
Request body
Content type: application/json (form fields are read too when there is no JSON body)
| Field | Type | Required | Description |
|---|---|---|---|
location_id |
integer |
Yes | The marina. Must be active and booked by the form. |
boat_id |
integer |
Yes | The boat. Must be stocked at the marina, active, offered by the form and priced. |
start |
string |
Yes | Departure, YYYY-MM-DD HH:MM on the marina’s clock. |
end |
string |
Yes | Return, in the same form. |
guests |
integer |
No | People on board, 1 by default. |
form_id |
integer |
No | The booking form to price on. Without it, the site’s default form. |
A quote is always for one boat, billed in the boat’s own unit: a quantity or billing_type sent is ignored. Fields a Pro app prices, such as extras or a coupon code, are read under the names that app gives them, the same as on the booking widget.
{
"location_id": 2,
"boat_id": 5,
"start": "2026-11-20 10:00",
"end": "2026-11-20 14:00",
"guests": 4
}
Responses
200 OK. data is the quote.
{
"success": true,
"message": "",
"data": {
"location_id": 2,
"boat_id": 5,
"billing_type": "hour",
"units": 4.0,
"quantity": 1,
"currency": "EUR",
"line_items": [
{
"type": "fee",
"label": "Booking fee",
"quantity": 1,
"unit_price": 20.0,
"total": 20.0
},
{
"type": "rental",
"reference_id": 5,
"label": "1 boat × 4 hours",
"quantity": 4.0,
"unit_price": 95.0,
"total": 380.0
}
],
"subtotal": 400.0,
"discount_total": 0.0,
"tax_total": 0.0,
"deposit_amount": 0.0,
"total": 400.0
}
}
| Field | Type | Meaning |
|---|---|---|
data.billing_type |
string |
The unit the boat is priced in |
data.units |
number |
How many of that unit the window is |
data.currency |
string |
The marina’s currency, else the site’s |
data.line_items |
array |
Each priced line: type (fee, rental, or a line a Pro app adds), label, quantity, unit_price, total. A line whose price was adjusted, by a pricing rule for example, also says how |
data.subtotal |
number |
The lines before any discount |
data.discount_total |
number |
What discounts take off, never more than the subtotal |
data.tax_total |
number |
What is added after the discount, such as tax |
data.deposit_amount |
number |
The part due now, 0 when the whole amount is due |
data.total |
number |
What the booking would cost |
A Pro app may add totals of its own, such as the sum of its extras.
Errors
| Status | Code | When |
|---|---|---|
422 |
location_unavailable |
The marina is missing, does not exist, is inactive, or the form does not book there. |
422 |
type_unavailable |
The boat is not stocked at the marina, is inactive, or the form does not offer it. |
422 |
no_price |
The boat has no price at the marina for its billing unit. |
410 |
form_unavailable |
form_id names a form that is not active. |
422 |
invalid_dates |
start or end is missing or unreadable. |
422 |
invalid_range / too_soon / too_far |
The return is not after the departure, or the departure is in the past, too soon or too far ahead. |
429 |
plugixa_boatrental_rate_limited |
Too many requests from this address. Retry-After says when to try again. |
403 |
plugixa_boatrental_key_scope |
An API key was sent. |
Plus the errors every endpoint can return.
Examples
curl -s -X POST "https://your-site.example/wp-json/pbr/v1/quote" \
-H "Content-Type: application/json" \
-d '{"location_id":2,"boat_id":5,"start":"2026-11-20 10:00","end":"2026-11-20 14:00","guests":4}'
<?php
$ch = curl_init('https://your-site.example/wp-json/pbr/v1/quote');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'location_id' => 2,
'boat_id' => 5,
'start' => '2026-11-20 10:00',
'end' => '2026-11-20 14:00',
'guests' => 4,
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.example/wp-json/pbr/v1/quote', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ location_id: 2, boat_id: 5, start: '2026-11-20 10:00', end: '2026-11-20 14:00', guests: 4 }),
});
const { data } = await response.json();
Quick Links
Share