Booking kit
The booking kit maps a typical reservation flow to three API calls. No new endpoints — use the existing check, deduct, and restore endpoints with stable request_id values.
| Step | When | Endpoint | Scope |
|---|---|---|---|
| 1. Check | Before the customer confirms | POST /api/v2/entitlements/check-eligibility | check |
| 2. Deduct | When the booking is confirmed | POST /api/v2/entitlements/deduct | deduct |
| 3. Restore | When the booking is cancelled within the window | POST /api/v2/entitlements/restore | restore |
Use the same location_id, contact id, and product_config_id (or calendar_id) across all three calls.
Idempotency keys
Section titled “Idempotency keys”- Deduct: set
request_idto your booking id (e.g.booking_123). - Restore: set
request_idto the booking id plus a suffix (e.g.booking_123-restore).
On timeout, resend the exact same payload with the same request_id — Kotally returns the original result without repeating the operation.
1. Before confirm — check eligibility
Section titled “1. Before confirm — check eligibility”Call check-eligibility when the customer selects a slot but before you charge or lock the booking. A 200 with ok: true means they have enough credits; ok: false tells you why not.
curl -X POST https://app.<your-domain>/api/v2/entitlements/check-eligibility \ -H "Authorization: Bearer ktly_<your-token>" \ -H "Content-Type: application/json" \ -d '{ "location_id": "loc_1", "external_contact_id": "crm_jane_1", "product_config_id": "pc_package_1", "amount": 1 }'2. On confirm — deduct credits
Section titled “2. On confirm — deduct credits”Call deduct when the booking is confirmed (or when your studio policy says credits are consumed — e.g. on booking created vs. on visit).
curl -X POST https://app.<your-domain>/api/v2/entitlements/deduct \ -H "Authorization: Bearer ktly_<your-token>" \ -H "Content-Type: application/json" \ -d '{ "location_id": "loc_1", "request_id": "booking_123", "external_contact_id": "crm_jane_1", "product_config_id": "pc_package_1", "amount": 1, "external_ref": "booking_123" }'3. On cancel — restore credits
Section titled “3. On cancel — restore credits”Call restore when a booking is cancelled and the appointment is still inside the workspace cancellation window. Pass appointment_time so Kotally can enforce the window.
curl -X POST https://app.<your-domain>/api/v2/entitlements/restore \ -H "Authorization: Bearer ktly_<your-token>" \ -H "Content-Type: application/json" \ -d '{ "location_id": "loc_1", "request_id": "booking_123-restore", "external_contact_id": "crm_jane_1", "product_config_id": "pc_package_1", "amount": 1, "external_ref": "booking_123", "appointment_time": "2026-05-01T10:00:00.000Z" }'Reason codes staff care about
Section titled “Reason codes staff care about”These reason_code values appear on check, deduct, and restore responses when ok is false:
reason_code | Meaning |
|---|---|
INSUFFICIENT_CREDITS | Contact does not have enough credits for the requested amount |
ENTITLEMENT_PAUSED | The matching entitlement is paused — credits cannot be used until unpaused |
ENTITLEMENT_EXPIRED | The matching entitlement has expired |
SERVICE_FAMILY_MISMATCH | Contact has credits, but not for this calendar or product config |
NO_ENTITLEMENT | Contact has no matching entitlement for this product config or calendar |
CANCELLATION_WINDOW_EXPIRED | Restore rejected — the appointment is past the allowed cancellation window |
See the Overview for HTTP status codes and the full reason-code list.