Releases
The release is the versioning unit, because it is atomic, matches git, and pins a journey together with the templates it sends. A pushed release is pending until it compiles, then ready or failed, and it runs nowhere until it is deployed. deployedIn is computed from the deployment log, so it always matches what an environment is actually running.
POST /v1/releases
Section titled “POST /v1/releases”Create a release from a built manifest
Auth: Clerk session token, or an org deploy key.
Request body
{ "data": { "manifest": { "protocol": 1, "sdk": "string", "journeys": [ { "key": "string", "tags": [], "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "environments": [ "development" ], "spine": [ { "name": "sleep", "detail": "string" } ], "bundle": "string" } ], "templates": [ { "key": "string", "tags": [], "sendClass": "marketing", "verifyLink": true, "propsSchema": { "key": {} }, "bundle": "string" } ], "source": "string" } }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.manifest |
object | yes | |
data.manifest.protocol |
1 | yes | |
data.manifest.sdk |
string | yes | length 1–∞ |
data.manifest.journeys |
object[] | yes | items 0–100 |
data.manifest.journeys[] |
object | yes | |
data.manifest.journeys[].key |
string | yes | length 0–64 |
data.manifest.journeys[].tags |
string[] | no | default []; items 0–20 |
data.manifest.journeys[].trigger |
object | object | yes | |
data.manifest.journeys[].purpose |
“emailMarketing” | “dataProcessing” | yes | |
data.manifest.journeys[].environments |
“development” | “production”[] | yes | items 1–∞ |
data.manifest.journeys[].spine |
object[] | yes | |
data.manifest.journeys[].spine[] |
object | yes | |
data.manifest.journeys[].spine[].name |
“sleep” | “waitForEvent” | “email.send” | “webhook.send” | “traits.set” | “traits.unset” | “profile.get” | “profiles.get” | “events.track” | “restart” | yes | |
data.manifest.journeys[].spine[].detail |
string | no | length 0–200 |
data.manifest.journeys[].bundle |
string | yes | |
data.manifest.templates |
object[] | yes | items 0–200 |
data.manifest.templates[] |
object | yes | |
data.manifest.templates[].key |
string | yes | length 0–64 |
data.manifest.templates[].tags |
string[] | no | default []; items 0–20 |
data.manifest.templates[].sendClass |
“marketing” | “transactional” | yes | |
data.manifest.templates[].verifyLink |
boolean | yes | |
data.manifest.templates[].propsSchema |
record<string, any> | yes | |
data.manifest.templates[].bundle |
string | yes | |
data.manifest.source |
string | yes |
Response 201
{ "data": { "id": "string", "orgId": "string", "projectId": "string", "seq": 42, "status": "pending", "manifest": { "protocol": 1, "sdk": "string", "journeys": [ { "key": "string", "tags": {}, "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "environments": [ "development" ], "spine": [ { "name": "sleep", "detail": "string" } ], "bundle": "string" } ], "templates": [ { "key": "string", "tags": {}, "sendClass": "marketing", "verifyLink": true, "propsSchema": { "key": {} }, "bundle": "string" } ], "source": "string", "modules": { "journeys": { "key": "string" }, "templates": { "key": "string" } }, "plugin": "string" }, "manifestDigest": "string", "createdBy": "string", "createdAt": "2026-01-15T09:30:00.000Z", "compiledAt": "2026-01-15T09:30:00.000Z", "error": "string", "deployedIn": [ "development" ] }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.id |
string | yes | |
data.orgId |
string | yes | |
data.projectId |
string | yes | |
data.seq |
integer | yes | -2147483648 ≤ x ≤ 2147483647 |
data.status |
“pending” | “ready” | “failed” | yes | |
data.manifest |
object | object | yes | |
data.manifestDigest |
string | yes | |
data.createdBy |
string | yes | |
data.createdAt |
string (date-time) | yes | |
data.compiledAt |
string (date-time) | null | yes | |
data.error |
string | null | yes | |
data.deployedIn |
“development” | “production”[] | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no |
Errors follow the shared envelope and code table.
GET /v1/releases
Section titled “GET /v1/releases”List releases, newest first
Auth: Clerk session token, or an org deploy key.
Query parameters
{ "cursor": "string", "limit": 50}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
Response 200
{ "data": [ { "id": "string", "orgId": "string", "projectId": "string", "seq": 42, "status": "pending", "manifest": { "protocol": 1, "sdk": "string", "journeys": [ { "key": "string", "tags": {}, "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "environments": [ "development" ], "spine": [ { "name": "sleep", "detail": "string" } ], "bundle": "string" } ], "templates": [ { "key": "string", "tags": {}, "sendClass": "marketing", "verifyLink": true, "propsSchema": { "key": {} }, "bundle": "string" } ], "source": "string", "modules": { "journeys": { "key": "string" }, "templates": { "key": "string" } }, "plugin": "string" }, "manifestDigest": "string", "createdBy": "string", "createdAt": "2026-01-15T09:30:00.000Z", "compiledAt": "2026-01-15T09:30:00.000Z", "error": "string", "deployedIn": [ "development" ] } ], "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object[] | yes | |
data[] |
object | yes | |
data[].id |
string | yes | |
data[].orgId |
string | yes | |
data[].projectId |
string | yes | |
data[].seq |
integer | yes | -2147483648 ≤ x ≤ 2147483647 |
data[].status |
“pending” | “ready” | “failed” | yes | |
data[].manifest |
object | object | yes | |
data[].manifestDigest |
string | yes | |
data[].createdBy |
string | yes | |
data[].createdAt |
string (date-time) | yes | |
data[].compiledAt |
string (date-time) | null | yes | |
data[].error |
string | null | yes | |
data[].deployedIn |
“development” | “production”[] | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no |
Errors follow the shared envelope and code table.
GET /v1/releases/{id}
Section titled “GET /v1/releases/{id}”Inspect one release
Auth: Clerk session token, or an org deploy key.
Response 200
{ "data": { "id": "string", "orgId": "string", "projectId": "string", "seq": 42, "status": "pending", "manifest": { "protocol": 1, "sdk": "string", "journeys": [ { "key": "string", "tags": {}, "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "environments": [ "development" ], "spine": [ { "name": "sleep", "detail": "string" } ], "bundle": "string" } ], "templates": [ { "key": "string", "tags": {}, "sendClass": "marketing", "verifyLink": true, "propsSchema": { "key": {} }, "bundle": "string" } ], "source": "string", "modules": { "journeys": { "key": "string" }, "templates": { "key": "string" } }, "plugin": "string" }, "manifestDigest": "string", "createdBy": "string", "createdAt": "2026-01-15T09:30:00.000Z", "compiledAt": "2026-01-15T09:30:00.000Z", "error": "string", "deployedIn": [ "development" ] }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.id |
string | yes | |
data.orgId |
string | yes | |
data.projectId |
string | yes | |
data.seq |
integer | yes | -2147483648 ≤ x ≤ 2147483647 |
data.status |
“pending” | “ready” | “failed” | yes | |
data.manifest |
object | object | yes | |
data.manifestDigest |
string | yes | |
data.createdBy |
string | yes | |
data.createdAt |
string (date-time) | yes | |
data.compiledAt |
string (date-time) | null | yes | |
data.error |
string | null | yes | |
data.deployedIn |
“development” | “production”[] | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no |
Errors follow the shared envelope and code table.
GET /v1/releases/{id}/source
Section titled “GET /v1/releases/{id}/source”Download the release’s source tarball
Auth: Clerk session token, or an org deploy key.
Errors follow the shared envelope and code table.
POST /v1/releases/{id}/cancel-executions
Section titled “POST /v1/releases/{id}/cancel-executions”Cancel every live execution pinned to this release
Auth: Clerk session token, or an org deploy key.
Response 202
{ "data": { "releaseId": "string", "environment": "development", "requested": 42, "workflowId": "string" }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.releaseId |
string | yes | |
data.environment |
“development” | “production” | yes | |
data.requested |
integer | yes | -9007199254740991 ≤ x ≤ ∞ |
data.workflowId |
string | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no |
Errors follow the shared envelope and code table.