Create an automation
Create a DRAFT automation, with its steps if you have them.
https://app.usenotix.dev/api/v1/automationsNeeds a full access key. Sending access keys cannot call this. Key permissions lists the extra rules some calls have.
Create a DRAFT automation, with its steps if you have them. A draft sends nothing: check it with GET /v1/automations/{id}/preflight and turn it on with POST /v1/automations/{id}/activate. A team can create 30 automations a minute.
Steps
steps is the whole list, at most 50. Step types:
| Type | What it does | Fields |
|---|---|---|
EMAIL | Sends one email | from, subject, optional previewText, content, replyTo, variables (the template's blanks) |
WAIT | Delay | seconds, 1 minute to 30 days |
WAIT_FOR_EVENT | Waits for your app to send an event | eventName, timeoutSeconds (up to 30 days), optional filter |
CONDITION | If / else | condition: a rule or an and / or group |
UPDATE_CONTACT | Changes the contact | firstName, lastName, unsubscribe: true, properties |
ADD_TO_SEGMENT | Puts the person in a segment | segmentId |
A rule is { "type": "rule", "field": "event.plan", "operator": "equals", "value": "pro" }. Operators: equals, not_equals, gt, gte, lt, lte, contains, starts_with, ends_with, exists, is_empty. A field or a { "var": "..." } value reads event.* (the event that started the run), contact.* or wait_events.<event name>.*.
connections say which step follows which: { "from": "trigger" | stepId, "to": stepId, "type": "default" }. An If / else leaves by yes and no, a Wait for event by received and timeout; a path with nothing after it ends the run. No path may loop back. Send connections with steps, giving every step an id; leave them out and the steps run one after another, in order. Keep the id of a step you already have so people in the automation stay on it.
content is a Notix editor document (JSON, as a string), checked the way the dashboard's editor checks it: a javascript: or data: link, an unknown node or a document deeper than 64 levels answers 400. Raw HTML is not accepted. To use a template, copy it into a step with POST /v1/automations/{id}/steps/{stepId}/template.
Who can call it
A full access key created by a team admin, as on the dashboard. Every refusal is 403:
| Code | Why |
|---|---|
SCOPE_DENIED | The key is not a full access key (send-only, read-only or live AI). |
FORBIDDEN | The key was made by a team member without admin rights, or before Notix recorded who made each key. Create a new key as a team admin. |
DOMAIN_PINNED | The key is limited to one domain and an email step, or the sender, is on another. |
A key limited to one domain sees only automations whose every email step sends from its domain; any other automation answers 404.
Body parameters
At most 255 characters.
CONTACT_ADDED: people join when they are added to contactBookId. API: your app enrols each person. EVENT: your app sends triggerEvent with POST /v1/events.
One of CONTACT_ADDED, API, EVENT.
The event an EVENT automation starts on.
Only contacts in this segment of the contact book join.
The journey's steps in order, at most 50. Replaces every step.
Which step follows which. Send it with steps, and give every step an id so connections can name it. Leave it out and the steps run one after another, in order. from is a step id or trigger.
A step id, or trigger.
At most 64 characters.
At most 64 characters.
One of default, yes, no, received, timeout. Default "default".
Headers
Bearer followed by your API key.
Errors
The body is not valid: a step, its editor document, the contact book or the segment.
`SCOPE_DENIED`: the key is not a full access key (send-only, read-only or live AI). `FORBIDDEN`: the key was made by a team member without admin rights, or before Notix recorded who made each key. `DOMAIN_PINNED`: the key is limited to one domain and an email would send from another.
The team created 30 journeys in the last minute.
Every error has the same shape. See all error codes.
curl -X POST "https://app.usenotix.dev/api/v1/automations" \
-H "Authorization: Bearer $NOTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome series",
"triggerType": "CONTACT_ADDED"
}'
import { Notix } from "notix-js";
const notix = new Notix(process.env.NOTIX_API_KEY);
const { data, error } = await notix.automations.create({
name: "Welcome series",
triggerType: "CONTACT_ADDED",
contactBookId: "cb_123",
steps: [
{ type: "EMAIL", from: "Acme <hello@acme.com>", subject: "Welcome to Acme" },
{ type: "WAIT", seconds: 2 * 24 * 3600 },
{ type: "EMAIL", from: "Acme <hello@acme.com>", subject: "Getting the most out of Acme" },
],
});
{
"id": "cly1jrn8x0000abcd1234",
"name": "Welcome series",
"status": "ACTIVE",
"triggerType": "CONTACT_ADDED",
"contactBookId": "cly1book0000abcd1234",
"segmentId": "cly1seg00000abcd1234",
"exitWhenLeavesSegment": false,
"triggerEvent": "payment.failed",
"steps": [
{
"id": "cm1x8f3k20001qz7v5b9d2e4a",
"type": "EMAIL",
"from": "Acme <receipts@acme.com>",
"subject": "Your receipt for order 4471"
}
],
"connections": [
{
"from": "trigger",
"to": "stp_a1b2c3d4e5f6"
}
],
"copiedFromId": "cm1x8f3k20001qz7v5b9d2e4a",
"stats": {
"enrolled": 1,
"active": 1,
"completed": 1,
"exited": 1,
"failed": 1,
"sentByStep": {
"stp_abc123": 12
}
},
"createdAt": "2026-10-01T09:00:00Z",
"updatedAt": "2026-10-01T09:00:00Z"
}