POST /api/v1/sequences/{sequenceId}/versions/{versionId}/nodes
Adds a node to a draft. Answers 201. Without afterNodeId the node is appended at the end of
the journey; with it, the node is slid in right after that node and the wires are stitched around
it.
A node carries one kind of column, the one of its type. A
wait with a templateId, or a
send_email with waitHours, answers 400 — the column would sit in the database meaning
nothing, read by neither the engine nor the screen. Sending the wrong column is never silently
dropped: you are told.POST with a templateId copies its subject and HTML onto
the node; editing the template afterwards changes nothing here. Without a templateId the node is
born empty — legal to create, refused at publication until you fill it with PATCH. Same for a
tag-less action node and a URL-less webhook: create now, complete before publishing.
A webhook URL is checked when you write it, not when it fires. A non-
https URL, or one
pointing inside a private network, answers 400 at write time. The call itself happens
at-most-once: it is never retried, so a destination that stops answering fails silently and
forever.Authorization
| Role in the organization | This endpoint |
|---|---|
OWNER | Allowed |
ADMIN | Allowed |
MEMBER | Refused — 403 |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
type | string | yes | send_email, wait, add_tag, remove_tag, end_sequence, webhook |
templateId | string | no | send_email only — copies the template's subject and HTML onto the node |
waitHours | number | yes | Whole hours to wait |
tagId | string | no | The tag the node puts on or takes off |
webhookUrl | string | no | The URL to call |
afterNodeId | string | no | Insert right after this node of the same version |
Example
bash
curl -X POST -H "x-api-key: $AGENTMAIL_API_KEY" -H "content-type: application/json" \
-d '{"type":"send_email","templateId":"'$TEMPLATE_ID'"}' \
"https://www.agentsmail.io/api/v1/sequences/$SEQUENCE_ID/versions/$VERSION_ID/nodes"Response
201 Created— the created resource.401 Unauthorized— missing or invalid key, or its owner left the organization.403 Forbidden— the key's owner is amemberof the organization, not anadmin.404 Not Found— no such resource, or it belongs to another organization. The API never confirms that an id exists to a caller who has no right to it.429 Too Many Requests— over 120 requests in a minute for this key.
Response fields
| Field | Type | Description |
|---|---|---|
success | boolean | Indicates if the operation was successful |
data.id | string | Unique identifier for the step |
data.versionId | string | The draft version it belongs to |
data.type | string | send_email, wait, add_tag, remove_tag, end_sequence, webhook |
data.subject | string | null | On a send_email step |
data.content | string | null | Same |
data.templateId | string | null | The template the step was copied from |
data.waitHours | number | null | Delay of a wait step |
data.tagId | string | null | Tag of an add_tag / remove_tag step |
data.webhookUrl | string | null | URL called by a webhook step |
data.createdAt | string | ISO creation date |
data.updatedAt | string | ISO date of the last change |
Example response
json
{
"success": true,
"data": {
"id": "4d19c0a2",
"versionId": "c41a7e55",
"type": "send_email",
"subject": "August news",
"content": "<html>…</html>",
"templateId": "5a44b901",
"waitHours": 24,
"tagId": "7c2ef4b1",
"webhookUrl": "https://example.com/hooks/agentsmail",
"createdAt": "2026-08-23T10:22:05.000Z",
"updatedAt": "2026-08-23T10:22:05.000Z"
}
}