Create an endpoint
const url = 'https://api.keptslot.com/v1/webhook-endpoints';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"url":"https://example.com/hooks/keptslot","events":["booking.created","booking.cancelled","booking.rescheduled","booking.no_show","payment.succeeded","payment.refunded","booking.held","booking.reminder","booking.staff_reminder","booking.expired","payment.disputed","payment.dispute_closed"]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.keptslot.com/v1/webhook-endpoints \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://example.com/hooks/keptslot", "events": [ "booking.created", "booking.cancelled", "booking.rescheduled", "booking.no_show", "payment.succeeded", "payment.refunded", "booking.held", "booking.reminder", "booking.staff_reminder", "booking.expired", "payment.disputed", "payment.dispute_closed" ] }'This endpoint registers a URL to receive events.
CAUTION: The response carries secret, and it is the only response
that ever does. Store it now. The stored form is sealed, so no later
call can show it to you. If you lose it, use the rotate endpoint and
store the new one.
Authorizations
Section titled “ Authorizations ”Request Body required
Section titled “ Request Body required ”object
Example
{ "url": "https://example.com/hooks/keptslot", "events": [ "booking.created", "booking.cancelled", "booking.rescheduled", "booking.no_show", "payment.succeeded", "payment.refunded", "booking.held", "booking.reminder", "booking.staff_reminder", "booking.expired", "payment.disputed", "payment.dispute_closed" ]}Responses
Section titled “ Responses ”The endpoint is created. This response carries secret.
object
The event types this endpoint receives. Twelve are subscribable:
booking.created, booking.cancelled, booking.rescheduled,
booking.no_show, payment.succeeded, payment.refunded,
booking.held, booking.reminder, booking.staff_reminder,
booking.expired, payment.disputed and
payment.dispute_closed.
booking.no_show fires when the business marks a no-show, not
when it clears one. The four payment events carry data.payment
beside data.booking; payment.succeeded fires once when the
charge succeeds, and payment.refunded once per increase of the
refund total, whoever issued the refund. An endpoint receives
only the events in this list. The webhooks guide describes each
event and its body.
How many deliveries failed in a row. It returns to 0 after a success.
The signing secret. It is present ONLY on the create response. The stored form is sealed and no read path can reveal it again. Store it now. If you lose it, rotate it.
Example
{ "events": [ "booking.created" ]}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 }}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 }}Two writes contended and one was rolled back. The request did nothing.
Retry it. The type field is transient_failure.
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 }}