Price a visit
const url = 'https://api.keptslot.com/v1/quote?service_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.keptslot.com/v1/quote?service_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \ --header 'Authorization: Bearer <token>'This endpoint gives the length, price and payment of one service with
the extras a customer has chosen, before anything is booked. Call it
each time the choice of extras changes, and show its
payment_amount_cents rather than the service’s own: with extras the
service’s amount no longer describes the visit.
Rate limited when called with a publishable key: 300 requests a
minute for the workspace’s whole booking page and 60 a minute for one
caller address, separate from the budget of GET /v1/availability.
Authorizations
Section titled “ Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “ Query Parameters ”The service to book. It must be active and bookable on its own
(standalone), or the endpoint refuses the request with a 422 on
service_id.
Extras to add to the service, as comma-separated ids. Each id must
be an extra offered with service_id, at most 10 and each once,
or the endpoint refuses the request with a 422 on extra_ids. An
empty value is refused too. Leave it out for the service alone.
Calendars to price the visit for, as comma-separated ids. Each id
must be a calendar that performs the service and every extra, or
the endpoint refuses the request with a 422 on staff_ids. An
empty value is refused too. With one id, the figures are that
calendar’s. With several, or with none, the figures are those of
the cheapest of them, and from says whether they differ.
Responses
Section titled “ Responses ”The visit’s figures.
object
The service plus every extra, in minutes.
The service plus every extra. It is null when none of them has a price.
The service’s payment_mode. It applies to the whole
visit; an extra’s own mode is not used.
What the customer pays at booking time. It is null when
payment_mode is none, when no amount can be computed,
and when the workspace cannot take a payment now. In the
last two cases a booking that needs a payment is refused,
so show the visit as unavailable.
The calendars that perform the service and every extra.
It lists all of them, whatever staff_ids asked for.
True when the calendars priced do not all charge the
same. price_cents and payment_amount_cents are then
the cheapest calendar’s, so show them as a starting
price.
Example
{ "duration_minutes": 150, "price_cents": 15000, "payment_mode": "deposit_percent", "payment_amount_cents": 3750, "staff_ids": [ "6f1c0b52-9a3e-4f77-8d21-0b5a2c9e4d10" ], "from": false}The key is missing, malformed or revoked.
object
object
A stable machine-readable code. Match on this.
A sentence for a person. Do not match on this.
The field that caused the refusal, if one field did.
The plan limit that refused the request. It is present only on a 402, and only for a secret key or an account key. See the errors guide.
The current count for that dimension. It is present only on a 402, and only for an account key. It is absent when the refusal has no count to report. Absent and zero are different answers.
The cap for that dimension. It is present only on a 402, and only for an account key. A cap of zero is a real value.
Example generated
{ "error": { "type": "example", "message": "example", "param": "example", "dimension": "example", "used": 1, "limit": 1 }}The request used a publishable key and sent an Origin header that is
not on the allowed list of that key. Add the origin to the key, or call
the endpoint with a secret key from a server. The type field is
origin_not_allowed.
object
object
A stable machine-readable code. Match on this.
A sentence for a person. Do not match on this.
The field that caused the refusal, if one field did.
The plan limit that refused the request. It is present only on a 402, and only for a secret key or an account key. See the errors guide.
The current count for that dimension. It is present only on a 402, and only for an account key. It is absent when the refusal has no count to report. Absent and zero are different answers.
The cap for that dimension. It is present only on a 402, and only for an account key. A cap of zero is a real value.
Example generated
{ "error": { "type": "example", "message": "example", "param": "example", "dimension": "example", "used": 1, "limit": 1 }}There is no such resource in this workspace.
object
object
A stable machine-readable code. Match on this.
A sentence for a person. Do not match on this.
The field that caused the refusal, if one field did.
The plan limit that refused the request. It is present only on a 402, and only for a secret key or an account key. See the errors guide.
The current count for that dimension. It is present only on a 402, and only for an account key. It is absent when the refusal has no count to report. Absent and zero are different answers.
The cap for that dimension. It is present only on a 402, and only for an account key. A cap of zero is a real value.
Example generated
{ "error": { "type": "example", "message": "example", "param": "example", "dimension": "example", "used": 1, "limit": 1 }}The request body or the query is not valid.
object
object
A stable machine-readable code. Match on this.
A sentence for a person. Do not match on this.
The field that caused the refusal, if one field did.
The plan limit that refused the request. It is present only on a 402, and only for a secret key or an account key. See the errors guide.
The current count for that dimension. It is present only on a 402, and only for an account key. It is absent when the refusal has no count to report. Absent and zero are different answers.
The cap for that dimension. It is present only on a 402, and only for an account key. A cap of zero is a real value.
Example generated
{ "error": { "type": "example", "message": "example", "param": "example", "dimension": "example", "used": 1, "limit": 1 }}This endpoint’s request budget is spent. The type field is
rate_limited.
The budget is a token bucket, not a calendar-minute counter: it
refills CONTINUOUSLY as time passes, a few tokens’ worth every
second, rather than resetting all at once at the top of the minute.
There is no wall-clock boundary to wait for. A REFUSED request costs
nothing – the check happens before a token is spent, so hammering
this endpoint while refused does not delay when it starts working
again. What you get back is Retry-After: seconds until the bucket
has refilled enough to admit one more request, computed from exactly
how empty the bucket is right now. Retrying before then just gets
refused again; retrying at or after Retry-After succeeds. See the
endpoint’s own description for the actual numbers – they differ by
endpoint and, for the publishable-key routes, by whether the budget
is shared by the whole workspace or is one caller’s own share of it.
The response also carries RateLimit-Remaining (requests left in
the bucket – always 0 on this response, since a refusal only
happens once it reaches zero). Both headers are ADDITIVE: type
alone is enough to act correctly, and a client that cannot read
response headers loses nothing. Access-Control-Expose-Headers
names both, so a browser-based integration on a publishable key can
read them too, the same as it reads type from the body.
object
object
A stable machine-readable code. Match on this.
A sentence for a person. Do not match on this.
The field that caused the refusal, if one field did.
The plan limit that refused the request. It is present only on a 402, and only for a secret key or an account key. See the errors guide.
The current count for that dimension. It is present only on a 402, and only for an account key. It is absent when the refusal has no count to report. Absent and zero are different answers.
The cap for that dimension. It is present only on a 402, and only for an account key. A cap of zero is a real value.
Example generated
{ "error": { "type": "example", "message": "example", "param": "example", "dimension": "example", "used": 1, "limit": 1 }}Headers
Section titled “ Headers ”Seconds until this bucket admits another request.
Requests left in the bucket. Always 0 on this response.
A fault on our side. Do not retry the same request in a loop. The
type field is internal_error.
object
object
A stable machine-readable code. Match on this.
A sentence for a person. Do not match on this.
The field that caused the refusal, if one field did.
The plan limit that refused the request. It is present only on a 402, and only for a secret key or an account key. See the errors guide.
The current count for that dimension. It is present only on a 402, and only for an account key. It is absent when the refusal has no count to report. Absent and zero are different answers.
The cap for that dimension. It is present only on a 402, and only for an account key. A cap of zero is a real value.
Example generated
{ "error": { "type": "example", "message": "example", "param": "example", "dimension": "example", "used": 1, "limit": 1 }}