Create an automation
Creates a draft automation.
A draft can be saved with errors, which issues lists; nothing runs until it is activated.
Guide: Automations
A project secret key: vh_sk_... for production, vh_sk_test_... for test. Keep it on your servers.
In: header
Path parameters
The project's id, proj_.... A secret key works only in the project it belongs to.
Request body
application/json
TypeScript definitions
Use the request body type in TypeScript.
The automation's name, 1 to 255 characters.
1 <= length <= 255What the automation is for, up to 1,000 characters.
The environment whose events and purchases the automation reacts to: production (the default) or test.
The draft to start with; an empty flow to fill in when omitted.
Examples
curl -X POST "https://api.voidhash.com/api/v1/projects/proj_tz4a98xxat96iws9zmbrgj3a/automations" \ -H "Authorization: Bearer vh_sk_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Welcome series", "description": "Greets new users and nudges them after a day.", "environment": "production", "definition": { "version": 1, "trigger": { "type": "person_signed_up", "config": {}, "next": "welcome" }, "nodes": [ { "id": "welcome", "type": "send_push", "config": { "title": "Hi {{ person.name | default: \\"there\\" }}", "body": "Glad you\'re here." }, "next": { "out": "wait" } }, { "id": "wait", "type": "delay", "config": { "duration": { "amount": 1, "unit": "days" } }, "next": { "out": "paid" } }, { "id": "paid", "type": "condition", "config": { "condition": { "match": "all", "rules": [ { "field": "person.entitlements", "operator": "contains", "value": "premium" } ] } }, "next": { "no": "nudge" } }, { "id": "nudge", "type": "send_push", "config": { "title": "Still thinking?", "body": "Your trial is waiting." }, "next": {} } ], "settings": { "reentry": "once", "exitOn": [ "$subscription.created" ] } } }'{ "id": "auto_p4n8c2v6x0z3q7w1e5r9t2y6", "projectId": "proj_tz4a98xxat96iws9zmbrgj3a", "name": "Welcome series", "description": "Greets new users and nudges them after a day.", "status": "draft", "environment": "production", "definition": { "version": 1, "trigger": { "type": "person_signed_up", "config": {}, "next": "welcome" }, "nodes": [ { "id": "welcome", "type": "send_push", "config": { "title": "Hi {{ person.name | default: \"there\" }}", "body": "Glad you're here." }, "next": { "out": "wait" } }, { "id": "wait", "type": "delay", "config": { "duration": { "amount": 1, "unit": "days" } }, "next": { "out": "paid" } }, { "id": "paid", "type": "condition", "config": { "condition": { "match": "all", "rules": [ { "field": "person.entitlements", "operator": "contains", "value": "premium" } ] } }, "next": { "no": "nudge" } }, { "id": "nudge", "type": "send_push", "config": { "title": "Still thinking?", "body": "Your trial is waiting." }, "next": {} } ], "settings": { "reentry": "once", "exitOn": [ "$subscription.created" ] } }, "revision": 1, "hasUnpublishedChanges": true, "activeVersionId": null, "triggerType": "person_signed_up", "activatedAt": null, "nextFireAt": null, "createdAt": "2026-03-04T15:30:00.000Z", "updatedAt": "2026-03-04T15:30:00.000Z", "issues": []}{ "error": { "type": "invalid_request", "code": "invalid_body", "message": "The request body is invalid: Missing key\n at [\"name\"]" }}{ "error": { "type": "unauthenticated", "code": "invalid_api_key", "message": "This secret key is not valid." }}{ "error": { "type": "permission_denied", "code": "automations_not_enabled", "message": "Automations are not enabled for this organization." }}{ "error": { "type": "not_found", "code": "project_not_found", "message": "There is no project proj_tz4a98xxat96iws9zmbrgj3a, or this credential cannot use it.", "param": "projectId" }}{ "error": { "type": "internal", "code": "internal_error", "message": "Something went wrong on our side. Try again, and contact support with the Request-Id header if it keeps failing." }}Response body
application/json
application/json
application/json
application/json
application/json
application/json
Errors
| Status | type | code | When |
|---|---|---|---|
| 403 | permission_denied | automations_not_enabled | Where automations are not turned on. |
It can also fail with the errors every operation shares, such as unauthenticated; see Errors.
More in Automations
- List automations
GET - Retrieve the automation catalog
GET - List audience cohorts
GET - Retrieve an automation
GET - Update an automation
PATCH - Check an automation
POST - Test an automation
POST - Activate an automation
POST - Pause an automation
POST - Archive an automation
POST - Unarchive an automation
POST - List an automation's versions
GET - Retrieve an automation's stats
GET - List an automation's runs
GET - Start a run
POST - Retrieve a run
GET - Cancel a run
POST - Retry a run
POST
Something wrong or missing on this page? Tell us by email or on Discord.