Quickstart
From a new API key to your first response.
1. Create a key
An organization admin creates keys in the dashboard under Developer. API access is included on Pro and up, and the plan is checked on every request, so a key stops working if the business moves down a plan.
The raw key is shown exactly once, when it is created, and cannot be recovered afterwards. Only a hash of it is stored.
sk_live_<key_id>_<secret>2. Send it as a bearer token
Authorization: Bearer only. No query parameter, no custom header, no cookie fallback: a credential in a URL ends up in access logs, referrers and browser history.
curl https://gaplessly.com/api/v1/organization \ -H "Authorization: Bearer sk_live_..."3. Call the endpoint for your engine
Eight endpoints exist today, all GET, all under /api/v1/, one for every :read scope.
| Endpoint | Scope | Engine |
|---|---|---|
GET /api/v1/clients | clients:read | Either |
GET /api/v1/organization | organization:read | Either |
GET /api/v1/services | services:read | Appointments |
GET /api/v1/providers | providers:read | Appointments |
GET /api/v1/appointments | appointments:read | Appointments |
GET /api/v1/tables | tables:read | Hospitality |
GET /api/v1/service-periods | service-periods:read | Hospitality |
GET /api/v1/reservations | reservations:read | Hospitality |
An engine-owned endpoint answers 403 wrong_vertical to a key from the other kind of organization, even when the key holds the scope: a scope says what a program may ask for, the engine says what the organization is.
4. Handle errors by code
Every failure is JSON with a human sentence and a stable code. Match on code, never on error.
{ "error": "human readable sentence", "code": "machine_readable_code" }| Status | Code | Means |
|---|---|---|
| 401 | missing_authorization | No Authorization: Bearer header |
| 401 | invalid_key | Wrong format, unknown key or digest mismatch |
| 401 | key_revoked / key_expired | Revoked in the dashboard, or past its expiry |
| 403 | insufficient_scope | Valid key, scope not held (required_scope says which) |
| 403 | wrong_vertical | The route belongs to the other engine |
| 403 | plan_required | The plan does not include API access |
| 429 | rate_limited | Over the per-key limit for this window |
A 401 means the credential is not usable, so retrying it will never succeed. A 403 means the credential is fine but may not do this.