Entagl API reference
The Entagl API lets your own software work with an Entagl workspace: contacts, conversations, messages, bookings, reminders, orders, products, AI calls and campaigns. Webhooks tell your systems the moment something happens. It is the same API the Entagl app for Make uses.
Base URL
https://api.entagl.com/api/v1Requests and responses are JSON over HTTPS. Field names are snake_case. IDs are integers unless an endpoint says otherwise. Times are ISO 8601 strings; responses use UTC.
Authentication
Send a token with every request in the Authorization header: Authorization: Bearer <token>. Two kinds of token work:
API key
For your own server code. Create one in the Entagl app under Settings → API Keys. Keys start with ai_. A key works on the workspace it was created in and has owner rights there, so keep it secret and never put it in a browser or mobile app.
OAuth 2.0 access token
Used by connectors such as the Entagl app for Make. The person signs in with their Entagl account, and the connector acts as that person with their role in the workspace. To build your own OAuth integration, contact support@entagl.com.
curl "https://api.entagl.com/api/v1/contacts?limit=2" \
-H "Authorization: Bearer ai_your_api_key"A missing header answers 401 unauthenticated. A wrong or revoked key answers 401 invalid_api_key. An expired OAuth token answers 401 invalid_token: refresh it and retry.
Workspaces & permissions
Every request works on exactly one workspace. An API key always uses its own workspace. An OAuth login can belong to several workspaces (owned, or joined as a team member): send the X-Entagl-Workspace header with the workspace ID to choose one. With a single workspace the header is optional. GET /me works without the header and lists every workspace the login can use.
curl "https://api.entagl.com/api/v1/me" \
-H "Authorization: Bearer <oauth_access_token>"
curl "https://api.entagl.com/api/v1/contacts" \
-H "Authorization: Bearer <oauth_access_token>" \
-H "X-Entagl-Workspace: <workspace_id from /me>"Without the header on a multi-workspace login you get 400 workspace_required; a workspace the login cannot access answers 403 workspace_forbidden. An ID that belongs to another workspace always answers 404 not_found, never 403.
Each endpoint below shows the permission it needs. Owners, admins and API keys pass every check. Team members pass when their role has that permission ticked under team settings: contacts, inbox, calendar, orders, business_pages, call_agent, campaigns or integrations. Without it the API answers 403 insufficient_permissions.
Requests & errors
Send bodies as JSON with Content-Type: application/json. Most endpoints reject unknown body fields with 422, so a typo never passes silently. Every error uses the same shape: a stable code to branch on, a readable message, and for validation errors a details list that points at each bad field.
{
"error": {
"code": "validation_failed",
"message": "Invalid email address",
"details": [
{ "path": "email", "message": "Invalid email address" }
]
}
}- 400Malformed request: invalid ID, invalid cursor, missing workspace header.
- 401Missing, invalid or expired token.
- 402Not enough credits for the action (for example sending a campaign).
- 403Authenticated, but not allowed: missing permission or workspace access.
- 404Not found, including IDs from another workspace.
- 409Conflict: duplicate name, wrong state, or an Idempotency-Key clash.
- 422Validation failed, or a business rule refused the change.
- 429Rate limit reached. See Retry-After.
- 500 / 502Entagl or the messaging channel failed. Check the outcome before you retry a write.
Routes marked Legacy response format predate these conventions: they return plain JSON objects or arrays and answer most errors as { "message": "…" }.
Pagination
Endpoints marked Paginated return the newest items first, in a list envelope. Ask for up to 100 items with limit (default 25). When has_more is true, pass next_cursor as starting_after to get the next page. Other lists return everything at once with has_more: false.
{
"object": "list",
"data": [
{
"object": "contact",
"id": 6789,
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+15551234567",
"tags": ["vip"]
}
],
"has_more": true,
"next_cursor": "6789"
}curl "https://api.entagl.com/api/v1/contacts?limit=100&starting_after=6789" \
-H "Authorization: Bearer ai_your_api_key"Idempotency
Every POST endpoint in the standard format accepts an Idempotency-Key header (up to 200 characters). Use a unique value per operation, such as a UUID. Entagl stores the first response for 24 hours: a retry with the same key and the same body gets that response back with Idempotent-Replayed: true, and nothing runs twice. Routes marked Legacy response format work differently, see below.
curl -X POST "https://api.entagl.com/api/v1/contacts" \
-H "Authorization: Bearer ai_your_api_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f9c1d2e-order-7781" \
-d '{ "first_name": "Jane", "phone": "+15551234567", "tags": ["vip"] }'- The same key with a different body answers
409 idempotency_key_reused. - While the first request is still running, or if it never finished, a retry answers
409 request_in_progress. Check the outcome, then retry with a new key. - Every outcome is stored, errors included. To try a failed request again, use a new key.
- Keys are scoped to the workspace and the credential.
Legacy routes. POST /messages also accepts Idempotency-Key (or a message_id in the body): a retry of a message it already accepted answers 202 with the same conversationId and is not processed twice, and the same key with a different body answers 409. POST /chat has no replay protection: a retry runs the AI again, so check the outcome before you retry it.
Rate limits
Each workspace can make 120 requests per minute, shared by all of its API keys and connections. Responses carry RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the window resets). Over the limit you get 429 rate_limited with a Retry-After header: wait that many seconds, then retry. The legacy API channel routes are not counted in this limit.