Journeys
One row per journey the environment’s current release deploys, addressed by the key its author gave the file. active is the author’s own rollout gate (the environments the journey declares); the enable switch is the operator’s, per organization and per environment, and it survives a redeploy. The spine is recorded at build time and is display only: what a journey does at run time is whatever its code decides. A trigger’s event, appId and segment are patterns in which * matches any run of characters, one or a list of them, and a pattern reaches Cowliss’s own system. events only when its literal prefix starts with system.: see Event patterns. Runs are on the Executions page.
GET /v1/journeys
Section titled “GET /v1/journeys”List the journeys deployed in the selected environment
Auth: Clerk session token.
Query parameters
{ "cursor": "string", "limit": 50, "enabled": "true", "q": "string", "tag": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
enabled |
“true” | “false” | no | |
q |
string | no | length 0–200 |
tag |
string | no | length 0–50 |
Response 200
{ "data": [ { "orgId": "string", "environment": "development", "key": "string", "releaseId": "string", "tags": [ "string" ], "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "active": true, "spine": [ { "name": "sleep", "detail": "string" } ], "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "enabled": true } ], "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object[] | yes | |
data[] |
object | yes | |
data[].orgId |
string | yes | |
data[].environment |
“development” | “production” | yes | |
data[].key |
string | yes | |
data[].releaseId |
string | yes | |
data[].tags |
string[] | yes | |
data[].trigger |
object | object | yes | |
data[].purpose |
“emailMarketing” | “dataProcessing” | yes | |
data[].active |
boolean | yes | |
data[].spine |
object[] | yes | |
data[].spine[] |
object | yes | |
data[].spine[].name |
“sleep” | “waitForEvent” | “email.send” | “webhook.send” | “traits.set” | “traits.unset” | “profile.get” | “profiles.get” | “events.track” | “restart” | yes | |
data[].spine[].detail |
string | no | length 0–200 |
data[].createdAt |
string (date-time) | yes | |
data[].updatedAt |
string (date-time) | yes | |
data[].enabled |
boolean | 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/journeys/{key}
Section titled “GET /v1/journeys/{key}”Inspect one journey
Auth: Clerk session token.
Response 200
{ "data": { "orgId": "string", "environment": "development", "key": "string", "releaseId": "string", "tags": [ "string" ], "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "active": true, "spine": [ { "name": "sleep", "detail": "string" } ], "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "enabled": true }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.orgId |
string | yes | |
data.environment |
“development” | “production” | yes | |
data.key |
string | yes | |
data.releaseId |
string | yes | |
data.tags |
string[] | yes | |
data.trigger |
object | object | yes | |
data.purpose |
“emailMarketing” | “dataProcessing” | yes | |
data.active |
boolean | yes | |
data.spine |
object[] | yes | |
data.spine[] |
object | yes | |
data.spine[].name |
“sleep” | “waitForEvent” | “email.send” | “webhook.send” | “traits.set” | “traits.unset” | “profile.get” | “profiles.get” | “events.track” | “restart” | yes | |
data.spine[].detail |
string | no | length 0–200 |
data.createdAt |
string (date-time) | yes | |
data.updatedAt |
string (date-time) | yes | |
data.enabled |
boolean | 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/journeys/{key}/stats
Section titled “GET /v1/journeys/{key}/stats”Journey operational stats
Auth: Clerk session token.
Response 200
{ "data": { "executions": { "entered": 42, "active": 42, "completed": 42, "failed": 42 }, "deliveries": { "byStatus": { "sent": 42 } } }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.executions |
object | yes | |
data.executions.entered |
integer | yes | -9007199254740991 ≤ x ≤ ∞ |
data.executions.active |
integer | yes | -9007199254740991 ≤ x ≤ ∞ |
data.executions.completed |
integer | yes | -9007199254740991 ≤ x ≤ ∞ |
data.executions.failed |
integer | yes | -9007199254740991 ≤ x ≤ ∞ |
data.deliveries |
object | yes | |
data.deliveries.byStatus |
record<sent | delivered | bounced | complained | failed | skipped_disabled | skipped_paused | skipped_suppressed | skipped_quota | skipped_frequency_cap | skipped_consent | skipped_domain | skipped_ssrf | would_send | would_skip_disabled | would_skip_paused | would_skip_suppressed | would_skip_quota | would_skip_frequency_cap | would_skip_consent | would_skip_domain | would_skip_ssrf, integer> | 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.
PATCH /v1/journeys/{key}
Section titled “PATCH /v1/journeys/{key}”Enable or disable a journey in the selected environment
Auth: Clerk session token.
Request body
{ "data": { "enabled": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.enabled |
boolean | yes |
Response 200
{ "data": { "orgId": "string", "environment": "development", "key": "string", "releaseId": "string", "tags": [ "string" ], "trigger": { "event": "string", "appId": "string" }, "purpose": "emailMarketing", "active": true, "spine": [ { "name": "sleep", "detail": "string" } ], "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "enabled": true }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.orgId |
string | yes | |
data.environment |
“development” | “production” | yes | |
data.key |
string | yes | |
data.releaseId |
string | yes | |
data.tags |
string[] | yes | |
data.trigger |
object | object | yes | |
data.purpose |
“emailMarketing” | “dataProcessing” | yes | |
data.active |
boolean | yes | |
data.spine |
object[] | yes | |
data.spine[] |
object | yes | |
data.spine[].name |
“sleep” | “waitForEvent” | “email.send” | “webhook.send” | “traits.set” | “traits.unset” | “profile.get” | “profiles.get” | “events.track” | “restart” | yes | |
data.spine[].detail |
string | no | length 0–200 |
data.createdAt |
string (date-time) | yes | |
data.updatedAt |
string (date-time) | yes | |
data.enabled |
boolean | 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.
POST /v1/journeys/{key}/dry-run
Section titled “POST /v1/journeys/{key}/dry-run”Dry-run a journey against a real user
Auth: Clerk session token.
Request body
{ "data": { "profileId": "string" }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.profileId |
string | yes | length 1–∞ |
Response 201
{ "data": { "id": "string", "orgId": "string", "environment": "development", "journeyKey": "string", "profileId": "string", "workflowId": "string", "runId": "string", "releaseId": "string", "status": "running", "step": "string", "timerDeadline": "2026-01-15T09:30:00.000Z", "journalEntries": 42, "error": "string", "startedAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "endedAt": "2026-01-15T09:30:00.000Z" }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.id |
string | yes | |
data.orgId |
string | yes | |
data.environment |
“development” | “production” | yes | |
data.journeyKey |
string | yes | |
data.profileId |
string | yes | |
data.workflowId |
string | yes | |
data.runId |
string | yes | |
data.releaseId |
string | yes | |
data.status |
“running” | “waiting” | “completed” | “failed” | “cancelled” | yes | |
data.step |
string | null | yes | |
data.timerDeadline |
string (date-time) | null | yes | |
data.journalEntries |
integer | yes | -2147483648 ≤ x ≤ 2147483647 |
data.error |
string | null | yes | |
data.startedAt |
string (date-time) | yes | |
data.updatedAt |
string (date-time) | yes | |
data.endedAt |
string (date-time) | null | 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.