Get a booking
const url = 'https://api.keptslot.com/v1/bookings/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/bookings/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \ --header 'Authorization: Bearer <token>'This endpoint returns one booking by id. It is the read to make when a webhook names a booking.
A cancelled or expired booking is still returned. An id from another workspace is a 404, the same as an id that does not exist.
Authorizations
Section titled “ Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “ Path Parameters ”The booking id.
Responses
Section titled “ Responses ”The booking.
object
When the booking last changed. Send it back as updated_since on
GET /v1/bookings to read everything that changed after it.
The customer’s manage link token. It is present only on the response that creates the booking. Store it then. No later response repeats it.
When this booking stops holding its slot. It is present only while the booking is on a hold, and absent otherwise.
Show this time rather than counting a fixed number of minutes from now. The window differs between a booking waiting on a code and one waiting on a card, and it is longer for a card because a 3DS redirect goes to the customer’s bank and back.
Present only when the service takes a payment, and only on the response that creates the booking. The key is absent for a service that takes no payment. It is never null, so a client can test for the key itself.
Use these fields to mount Stripe’s Payment Element on the connected account and confirm the payment. The client secret works once, for this booking.
object
What this booking costs, in the smallest unit of the currency. It is a snapshot taken when the booking was made. Changing the service’s price later never changes it.
The business’s Stripe account. Pass it as stripeAccount when you
construct Stripe.js.
The Stripe publishable key to construct Stripe.js with. It is not
your Keptslot pk_ key.
The extras booked with the service, in the order the business lists them. Empty when there are none.
One extra on a booking, as it was when the booking was made. A later change to the service does not change it.
object
The price of the whole visit when it was booked: the service plus every extra. It is null when none of them had a price.
The price of the service alone when it was booked, without its extras. It is null when the service had no price.
The record sent with POST /v1/bookings. It is {} when none was
sent, never null.
object
Example generated
{ "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "staff_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "service_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "customer_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "starts_at": "2026-04-15T12:00:00Z", "ends_at": "2026-04-15T12:00:00Z", "status": "example", "updated_at": "2026-04-15T12:00:00Z", "access_token": "example", "hold_expires_at": "2026-04-15T12:00:00Z", "payment": { "client_secret": "example", "amount_cents": 1, "currency": "example", "connected_account_id": "example", "stripe_publishable_key": "example" }, "extras": [ { "service_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "name": "example", "duration_minutes": 1, "price_cents": 1 } ], "price_cents": 1, "service_price_cents": 1, "metadata": { "additionalProperty": "example" }}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 }}This is a server route and you sent a publishable key. Send a secret
key from your server. The type field is secret_key_required.
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 }}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 }}