Quotes
POST /v1/quotes prices a stay. It doesn’t hold anything — it’s a read,
just a priced one. A quote is valid for 15 minutes; hold the stay before
expiresAt or ask for a new one.
Request
Section titled “Request”| Field | Required | Notes |
|---|---|---|
resourceId |
yes | |
ratePlanId |
if the resource has a room type | Get it from GET /v1/resources/{id} — see Resources, room types, rate plans |
from, to |
yes | ISO 8601 datetimes; from must be strictly before to |
partySize |
yes | positive integer |
currency |
no | Display currency; defaults to the rate plan’s own currency (no conversion) |
curl -X POST https://api.<domain>/v1/quotes \ -H "Authorization: Bearer sk_test_..." \ -H "Content-Type: application/json" \ -d '{ "resourceId": "<RESOURCE_ID>", "ratePlanId": "<RATE_PLAN_ID>", "from": "2026-08-01T00:00:00Z", "to": "2026-08-04T00:00:00Z", "partySize": 2 }'const { data: quote, error } = await client.POST("/v1/quotes", { body: { resourceId: "<RESOURCE_ID>", ratePlanId: "<RATE_PLAN_ID>", from: "2026-08-01T00:00:00Z", to: "2026-08-04T00:00:00Z", partySize: 2, },});if (error) throw error;Response (trimmed)
Section titled “Response (trimmed)”{ "quoteId": "...", "priceBreakdown": { "nights": [ { "date": "2026-08-01", "baseAmountMinorUnits": "1500000", "amountMinorUnits": "1500000", "seasonalMultiplierBps": 0, "dayOfWeekMultiplierBps": 0 } ], "subtotalMinorUnits": "4500000", "lengthOfStayAdjustment": null, "totalMinorUnits": "4500000", "currency": "IDR" }, "fx": null, "displayTotal": { "currency": "IDR", "amountMinorUnits": "4500000" }, "signedQuoteToken": "eyJhbGciOi...", "expiresAt": "2026-07-16T03:15:00.000Z"}Money on the wire
Section titled “Money on the wire”null when no currency conversion happened — you didn’t ask for one, or it
already matched the rate plan’s own currency. When it’s present,
displayTotal is the converted amount the guest actually sees;
priceBreakdown.totalMinorUnits/.currency always stays in the rate
plan’s native currency either way.
signedQuoteToken
Section titled “signedQuoteToken”Hand this to hold creation unchanged (see Quickstart) — whoever confirms the hold trusts this token’s price, never a re-typed number.
Errors
Section titled “Errors”| Status | code |
Meaning |
|---|---|---|
| 400 | invalid_window |
from isn’t strictly before to |
| 400 | rate_plan_required |
The resource has a room type; you omitted ratePlanId |
| 404 | resource_not_found / rate_plan_not_found |
Check the ID, and check you’re using the right tenant’s key |
| 409 | unavailable |
See reasons — same vocabulary as Availability |
| 422 | no_pricing_rule |
No price configured for one or more nights (missingDates) — an operator-side gap, not something your integration can fix |
| 422 | fx_rate_unavailable |
No FX rate for the currency you asked for |
Both sk_ and pk_ keys can call this endpoint — it’s the widget’s
pricing surface too.