Get a key and make your first call
This guide books one appointment with curl. It takes six steps. The base URL
is https://api.keptslot.com.
Read the glossary first if you have not. One noun
here does not mean what the dashboard calls it: staff is a bookable
calendar, not a person with a login.
1. Create a secret key
Section titled “1. Create a secret key”- Open the dashboard and select your workspace.
- Go to Developer → API keys.
- Create a key of type Secret.
CAUTION: The full key value is shown once. Store it now. A later read gives
null, and no support call can recover it. If you lose the key, revoke it and
create another one.
A secret key starts with sk_. Keep it on your server. Do not put it in a
browser. For the difference between the key types, read the
keys guide.
2. Make sure that the key works
Section titled “2. Make sure that the key works”Every call sends the key as a bearer token.
curl https://api.keptslot.com/v1/workspace \ -H "Authorization: Bearer sk_4bT1nQ7xLd9sVzK0pR2eYw8hC6jM3gF5uA1oS7iN0dE"A 200 returns your workspace settings:
{ "name": "Northside Barbers", "timezone": "Europe/London", "currency": "GBP", "slot_interval_minutes": 15, "require_booking_verification": false}If the response is a 401, the key is wrong or revoked. If the response is a
403 with secret_key_required, you sent a publishable key.
Note the timezone. Every time in this API is an RFC3339 timestamp, and the
responses use the timezone of the workspace. The appointment happens at the
business, so the offset is the business’s and not the customer’s.
3. List your services
Section titled “3. List your services”A booking is always for exactly one service. Get the service id first.
curl https://api.keptslot.com/v1/services \ -H "Authorization: Bearer sk_4bT1nQ7xLd9sVzK0pR2eYw8hC6jM3gF5uA1oS7iN0dE"{ "data": [ { "id": "3a7b1e90-2c4d-4f81-9b02-7e5c1a6d8f44", "name": "Cut and finish", "duration_minutes": 45, "price_cents": 4000, "active": true } ]}This endpoint returns inactive services too. Read active to tell them apart.
A customer cannot book an inactive service.
4. Read the open slots
Section titled “4. Read the open slots”Ask for one service and one date range. The range must be 62 days or less.
curl -G https://api.keptslot.com/v1/availability \ -H "Authorization: Bearer sk_4bT1nQ7xLd9sVzK0pR2eYw8hC6jM3gF5uA1oS7iN0dE" \ --data-urlencode "service_id=3a7b1e90-2c4d-4f81-9b02-7e5c1a6d8f44" \ --data-urlencode "from=2026-09-01T00:00:00+01:00" \ --data-urlencode "to=2026-09-08T00:00:00+01:00"The slots are grouped by calendar:
{ "data": [ { "staff_id": "6f1c0b52-9a3e-4f77-8d21-0b5a2c9e4d10", "slots": [ { "start": "2026-09-01T09:00:00+01:00", "end": "2026-09-01T09:30:00+01:00" }, { "start": "2026-09-01T09:30:00+01:00", "end": "2026-09-01T10:00:00+01:00" } ] } ]}An empty data array means the range has no open slots. It is not an error.
5. Create the booking
Section titled “5. Create the booking”Send one slot start from step 4. If you omit staff_id, the API picks an open
calendar for you.
curl -X POST https://api.keptslot.com/v1/bookings \ -H "Authorization: Bearer sk_4bT1nQ7xLd9sVzK0pR2eYw8hC6jM3gF5uA1oS7iN0dE" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \ -d '{ "service_id": "3a7b1e90-2c4d-4f81-9b02-7e5c1a6d8f44", "starts_at": "2026-09-01T09:00:00+01:00", "customer": { "name": "Sam Okafor", "email": "sam@example.com", "phone": "+447700900123" } }'{ "id": "b41d9f2a-6c58-4a13-9d77-2e8f0c3b5a91", "staff_id": "6f1c0b52-9a3e-4f77-8d21-0b5a2c9e4d10", "service_id": "3a7b1e90-2c4d-4f81-9b02-7e5c1a6d8f44", "customer_id": "d2f4a6c8-1b3e-4d5f-8a70-9c1e2b4d6f80", "starts_at": "2026-09-01T09:00:00+01:00", "ends_at": "2026-09-01T09:45:00+01:00", "status": "confirmed", "access_token": "kQ8xR2vN7pL0aY4tB6cW1zJ5hM3sD9fG2uE7iO0nX4k"}Two fields decide what happens next.
access_token is on this response and on no other. It is the customer’s manage
link. Store it now.
status is confirmed or pending. If the status is confirmed, you are
done. If the status is pending, go to step 6.
Send an Idempotency-Key on every create, as the sample does. A retry with the
same key and the same body returns the stored response instead of a second
booking. Read the rate limits guide for what a repeat
returns.
6. Verify a pending booking
Section titled “6. Verify a pending booking”A pending booking holds the slot and is not confirmed. The customer gets a
6-digit code by email. Send that code back.
curl -X POST https://api.keptslot.com/v1/bookings/b41d9f2a-6c58-4a13-9d77-2e8f0c3b5a91/verify \ -H "Authorization: Bearer sk_4bT1nQ7xLd9sVzK0pR2eYw8hC6jM3gF5uA1oS7iN0dE" \ -H "Content-Type: application/json" \ -d '{ "code": "482915" }'{ "status": "confirmed" }Every refusal here returns the same error. A wrong code, an expired hold, too many attempts and an unknown booking are not told apart. The response is deliberately not an oracle for a 6-digit code.
Decide this step from the status on the create response. Do not decide it
from require_verification on the bootstrap response. A business can change
that setting at any time.
What to read next
Section titled “What to read next”- Availability and booking, end to end — the same flow from a browser, with the publishable key.
- Receive and verify a webhook — how to hear about a booking you did not make.
- Errors — every error type, and the one error whose body changes with your key.