Automations API
List automation workflows and programmatically enroll contacts in them. This is the primary way to trigger behavior-driven email sequences from your application backend.
The Automation Object
Automations are multi-step workflows triggered by contact events, time-based conditions, or manual enrollment via the API. They are created and edited in the dashboard.
{
"id": "clx_auto_welcome_seq_id",
"name": "Welcome Sequence",
"status": "active",
"triggerType": "CONTACT_CREATED",
"stepCount": 5,
"enrolledCount": 1842,
"completedCount": 1508,
"createdAt": "2026-01-08T10:00:00Z",
"updatedAt": "2026-03-15T09:30:00Z"
}Endpoints
Automation endpoints require the automations:read or automations:write scope.
List Automations
/api/v1/automationsscope: automations:readReturns a paginated list of all automations in the workspace, including their trigger type, step count, and enrollment stats.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| page | integer | query | optional | Page number (default: 1) |
| limit | integer | query | optional | Results per page, max 100 (default: 50) |
Response
{
"data": [
{
"id": "clx_auto_welcome_seq_id",
"name": "Welcome Sequence",
"status": "active",
"triggerType": "CONTACT_CREATED",
"stepCount": 5,
"enrolledCount": 1842,
"completedCount": 1508,
"createdAt": "2026-01-08T10:00:00Z",
"updatedAt": "2026-03-15T09:30:00Z"
},
{
"id": "clx_auto_purchase_flow_id",
"name": "Post-Purchase Flow",
"status": "active",
"triggerType": "CUSTOM_EVENT",
"stepCount": 3,
"enrolledCount": 742,
"completedCount": 694,
"createdAt": "2026-02-01T12:00:00Z",
"updatedAt": "2026-04-10T08:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 6,
"totalPages": 1
}
}Get an Automation
/api/v1/automations/{id}scope: automations:readFetch a single automation by ID, including its ordered list of steps. Returns 404 if the automation doesn't exist or belongs to a different workspace.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| id | string | path | required | Automation ID |
Response
{
"data": {
"id": "clx_auto_welcome_seq_id",
"name": "Welcome Sequence",
"description": "Onboarding emails for new signups",
"status": "ACTIVE",
"trigger": "SIGNUP",
"triggerConfig": {},
"createdAt": "2026-01-08T10:00:00Z",
"updatedAt": "2026-03-15T09:30:00Z",
"steps": [
{ "id": "stp_1", "type": "EMAIL", "position": 0, "subject": "Welcome to Acme", "delayMinutes": 0 },
{ "id": "stp_2", "type": "WAIT", "position": 1, "subject": null, "delayMinutes": 1440 },
{ "id": "stp_3", "type": "EMAIL", "position": 2, "subject": "Getting started", "delayMinutes": 0 }
]
}
}Update an Automation
/api/v1/automations/{id}scope: automations:writeUpdate name, description, status, trigger, or triggerConfig on an existing automation. Send only the fields you want to change. Returns 400 if the body has no updatable fields.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| id | string | path | required | Automation ID |
| name | string | body | optional | New name. Cannot be empty. Max 200 chars. |
| description | string | body | optional | New description. Pass null to clear. |
| status | string | body | optional | One of: DRAFT, ACTIVE, PAUSED, ARCHIVED. |
| trigger | string | body | optional | One of: LIST_ADDED, TAG_ADDED, EVENT, SIGNUP. |
| triggerConfig | object | body | optional | Trigger-specific config (e.g., listId, tagName, eventName). |
Request Body
{
"name": "Welcome Sequence v2",
"status": "PAUSED"
}Response
{
"data": {
"id": "clx_auto_welcome_seq_id",
"name": "Welcome Sequence v2",
"description": "Onboarding emails for new signups",
"status": "PAUSED",
"trigger": "SIGNUP",
"triggerConfig": {},
"createdAt": "2026-01-08T10:00:00Z",
"updatedAt": "2026-04-27T11:15:00Z",
"steps": [ /* ...same shape as Get an Automation */ ]
}
}Delete an Automation
/api/v1/automations/{id}scope: automations:writePermanently delete an automation along with its steps and all contact enrollments. This cannot be undone. Returns 404 if the automation doesn't exist.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| id | string | path | required | Automation ID |
Response
{
"data": {
"id": "clx_auto_welcome_seq_id",
"deleted": true
}
}Cascading delete
status: ARCHIVED via PATCH instead if you want to stop new enrollments without losing history.Enroll a Contact
Manually enroll a contact in an automation workflow. This bypasses the automation's configured trigger — the contact enters immediately at step 1 of the automation.
Common use cases include:
- Enrolling a contact in a welcome sequence after they complete a purchase outside of EmailSendX.
- Triggering a re-engagement flow from your CRM when a customer status changes.
- Enrolling contacts in a beta onboarding sequence when they're approved for a feature.
/api/v1/automations/{id}/enrollscope: automations:writeEnroll a contact in an automation. Returns 202 Accepted. If the contact is already active in this automation, the request is a no-op.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| id | string | path | required | Automation ID to enroll the contact in |
| contactId | string | body | required | ID of the contact to enroll |
| merge | object | body | optional | Optional key-value pairs merged into the contact's metadata before enrollment begins |
Request Body
{
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"merge": {
"enrollmentSource": "checkout",
"plan": "pro"
}
}Response
{
"data": {
"automationId": "clx_auto_welcome_seq_id",
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"enrolled": true,
"matchingAutomations": 1,
"enrolledAt": "2026-04-22T10:30:00Z"
}
}Enrollment is idempotent
enrolled: false and matchingAutomations: 0. The existing enrollment is not interrupted. Safe to call repeatedly without risk of duplicate emails.Enrollment examples in multiple languages:
curl -X POST \
https://emailsendx.com/api/v1/automations/clx_auto_welcome_seq_id/enroll \
-H "Authorization: Bearer esx_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"merge": { "plan": "pro" }
}'Need event-driven automation?
Instead of direct enrollment, fire a custom event on the contact and let matching automations trigger automatically.