API Keys
Use API keys to authenticate calls to the public REST API at
https://api.spelo.ai/v1/public/*. Every key is scoped to a single site —
keys never reach across sites.
Creating a key
Dashboard → Site → Settings → API Keys → Create key.
Pick a name that describes the integration (e.g. “HubSpot integration”, “Zapier — Slack notifier”). On success the dashboard shows the plaintext key once:
sk_live_abc123def456ghi789jkl012mno345pqr678stu9-vwxyz0123AFormat: sk_live_<43-char base64url> — 32 bytes (256 bits) of CSPRNG entropy.
Using a key
Send it as a Bearer token:
GET /v1/public/leads?limit=10 HTTP/1.1Host: api.spelo.aiAuthorization: Bearer sk_live_abc123...curl -H "Authorization: Bearer sk_live_abc123..." \ https://api.spelo.ai/v1/public/leads?limit=10Revoking a key
Dashboard → Settings → API Keys → trash icon → confirm.
A revoked key returns 401 UNAUTHENTICATED on the very next request. There
is no grace period.
Rate limits
API keys share the per-site rate limit budget (60 req/min). A per-key bucket is on the roadmap — until then, if you run multiple integrations against the same site, expect them to share that budget.
Response headers when rate-limited:
HTTP/1.1 429 Too Many RequestsRetry-After: 12X-RateLimit-Limit: 60X-RateLimit-Remaining: 0X-RateLimit-Reset: 12Error responses
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHENTICATED | missing, invalid, or revoked key |
| 403 | FORBIDDEN | key valid but the requested resource isn’t on its site |
| 404 | LEAD_NOT_FOUND / CONVERSATION_NOT_FOUND | no row for the given id on this key’s site |
| 429 | RATE_LIMITED | per-site budget exhausted |
Security notes
- Treat keys like passwords. Store them in your secrets manager, not your repo.
- Rotate when a contractor leaves or a laptop is lost.
- Each environment (staging, prod) should have its own key.
- Logs do not include the plaintext — Spelo only ever sees the SHA-256 hash and the last 4 characters in the dashboard list.
See also
- Leads endpoints
- Conversations endpoints
- Webhooks — push instead of pull