Developers

REST API v1

Public REST for locations, queues, and entries

Server-to-server HTTP on your Convex site URL. Staff still sign in with WorkOS AuthKit; integrations use Bearer API keys.

Base URL

All routes live under your Convex HTTP site URL (Dashboard → Settings → URL ending in .convex.site). Do not call Convex function URLs (*.convex.cloud).

{CONVEX_SITE_URL}/api/v1

Authentication

  1. In Esperaly: Organisation settings → Integrations (admin or owner).
  2. Create an API key. Copy it once — Esperaly stores a hash, not the secret.
  3. Send it on every request.
Authorization: Bearer esperaly_live_<secret>

Keys can be scoped and optionally restricted to specific locations. Demo organisations reject API keys. Never log the raw key. Revoked, expired, or unknown keys return 401.

Scopes

ScopeAllows
locations:readList organisation locations
queues:readList queues and fetch one queue
queue_entries:readList and get ticket entries
queue_entries:writeCreate, call, cancel, and complete entries
counters:readInclude counters on queue detail when the location uses counters

Example

curl -sS "$CONVEX_SITE_URL/api/v1/locations" \
  -H "Authorization: Bearer esperaly_live_…"

Create an entry (Idempotency-Key is stored for 24 hours):

curl -sS -X POST "$CONVEX_SITE_URL/api/v1/queues/$LOCATION_ID/entries" \
  -H "Authorization: Bearer esperaly_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"serviceId":"…","customerName":"Ada Lovelace"}'

Routes

MethodPathScopeNotes
GET/locationslocations:readOrganisation locations
GET/queuesqueues:readSame locations as queues (id = location id)
GET/queues/:queueIdqueues:readWaiting/active counts; counters if counters:read
GET/queues/:queueId/entriesqueue_entries:readActive tickets, cursor pagination
POST/queues/:queueId/entriesqueue_entries:writeCreate via the same intake engine as the dashboard
GET/entries/:entryIdqueue_entries:readOne ticket
PATCH/entries/:entryId405 in v1 (no safe patch mutation)
POST/entries/:entryId/callqueue_entries:writeMoves the ticket to the workflow Call Next status. Body { "counterId" } required when the location uses counters
POST/entries/:entryId/cancelqueue_entries:writeWorkflow leave/cancel status
POST/entries/:entryId/completequeue_entries:writeWorkflow complete status

Pagination: ?limit=25&cursor=… (max 100). Response { data, hasMore, cursor }.

Idempotency-Key on POST create: same key + same path returns the same ticket for 24 hours.

Errors

{ "error": { "code": "unauthorized", "message": "Invalid or missing API key", "requestId": "…" } }

CORS allows the Esperaly site origin only (not *). Server-to-server callers (curl, Zapier, your backend) do not need a browser origin.

Not in this release

Product OAuth (PKCE / refresh tokens), a hosted MCP server, and an official Zapier app are not shipped. Use API keys plus REST, or Webhooks by Zapier with a Catch Hook.

All developer docs · OpenAPI