REST API
Everything the dashboard does, programmable. Bearer-token authentication, predictable resource-oriented endpoints, JSON in, JSON out.
Base URL
https://leadiosa.com/api/v1
All endpoints are TLS-only. HTTP requests are redirected to HTTPS; clients that don't follow redirects will fail.
Authentication
The API uses bearer tokens scoped to a single workspace. Mint a token under Settings → API → Tokens. Pass it on every request:
curl https://leadiosa.com/api/v1/conversations \ -H "Authorization: Bearer $LEADIOSA_TOKEN"
Request and response format
- All bodies are JSON. Send
Content-Type: application/jsonon writes. - Timestamps are ISO-8601 strings in UTC, e.g.
2026-05-12T07:28:25.901Z. - Resource IDs are opaque strings — don't assume UUID-shape or numeric. They're stable across the lifetime of the resource.
- Empty optional fields are omitted, not
null.
Errors
Errors return a standard envelope:
{
"error": {
"code": "conversation_not_found",
"message": "Conversation conv_8f3c12 does not belong to this workspace.",
"request_id": "req_a1b2c3"
}
}| Status | When |
|---|---|
| 400 | Validation error. See the error message for which field. |
| 401 | Missing or invalid Authorization header. |
| 403 | Token is valid but lacks permission for this resource. |
| 404 | Resource not found (or not in this workspace). |
| 409 | Conflict — e.g. trying to assign a closed conversation. |
| 422 | Semantic validation failure — body looks valid but cannot be processed. |
| 429 | Rate limited. See Retry-After header. |
| 500 | Something broke on our side. Include the request_id when reporting. |
Pagination
List endpoints use cursor pagination:
curl "https://leadiosa.com/api/v1/conversations?limit=50&after=cur_xyz" \ -H "Authorization: Bearer $LEADIOSA_TOKEN"
{
"data": [ /* ...items... */ ],
"pagination": {
"has_more": true,
"next_cursor": "cur_abc"
}
}Default limit is 25, maximum 100. Cursors are opaque and only valid until the underlying data changes — pass after verbatim to fetch the next page.
Rate limits
Limits are per workspace, per token, per minute. Headers on every response tell you where you stand:
X-RateLimit-Limit: 300 X-RateLimit-Remaining: 287 X-RateLimit-Reset: 1747038505
A 429 response includes a Retry-After header (seconds). Back off; don't retry tight.
Resources
A full per-endpoint reference is rolling out; meanwhile, the resource map looks like this:
| Resource | Endpoints | Description |
|---|---|---|
conversations | GET, POST, PATCH | Conversation lifecycle, status transitions, assignment. |
messages | GET, POST | Append a message, list a conversation’s thread. |
contacts | GET, PATCH, DELETE | Contact records, attributes, GDPR erasure. |
notes | GET, POST | Internal notes on conversations. Never visible to the contact. |
knowledge | GET, POST, PATCH, DELETE | Knowledge-base articles and chunks. Manual ingest path. |
webhooks | GET, POST, DELETE | Webhook endpoints and the secret used to sign them. |
audit | GET | Read-only audit log. Useful for compliance exports. |
workspace | GET, POST | Workspace lifecycle: archive-status, close, restore. Owner-only. |
billing/subscription | GET | Current plan, billing cycle, AI token usage. Read-only. |
/docs/api/... subroutes — being filled out resource by resource. The OpenAPI spec is downloadable from /api/v1/openapi.json.Versioning and deprecation
The current major version is v1. Breaking changes ship under a new major. Within a major:
- New endpoints and new fields are additive — they will not break clients that ignore unknown fields.
- Deprecations are announced via the X-API-Deprecation response header and emailed to workspace owners at least 90 days before removal.
- Bug fixes and tightening of validation may land at any time, with notice when behaviour changes are observable.
See Webhooks for the equivalent event catalogue.