Releases & Automation

Manage SaaS package release lifecycle, desktop distribution, container deployments, feature flags, campaigns, automation rules, time triggers, workflows, and change management.

95 endpoints. Generated from the OpenAPI 3.1 specification.

GET /v1/automation-rules

List automation rules

Returns automation rules for the authenticated organization. Supports optional filters: `is_enabled` (`true`/`false`), `trigger_type`, `action_type`, `page`, `page_size` (max 200).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
is_enabled query string (enum) no Filter by enabled state.
trigger_type query string no Filter by trigger type string.
action_type query string no Filter by action type string.
page query integer no Page number (1-based).
page_size query integer no Results per page (max 200).

Responses

StatusDescription
200 Automation rule list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
rules array of object
total_count integer
page integer
page_size integer
POST /v1/automation-rules

Create an automation rule

Creates an automation rule. For `webhook` action types `action_config.url` must use HTTPS and `action_config.method` must be present. For `run_ai_session` action types `action_config.prompt` must be a non-empty string. For `cron` trigger types `trigger_config.expression` must be a valid 5-field cron expression.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
description string no
trigger_type string yes
trigger_config object yes
action_type string yes
action_config object yes
is_enabled boolean no

Responses

StatusDescription
201 Automation rule created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
409 `CONFLICT` — a rule with the same name already exists.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
trigger_type string
trigger_config object
action_type string
action_config object
is_enabled boolean
created_at string<date-time>
GET /v1/automation-rules/{ruleId}

Get an automation rule

Returns a single automation rule by ID.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Automation rule identifier (UUIDv7).

Responses

StatusDescription
200 Automation rule record.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
trigger_type string
trigger_config object
action_type string
action_config object
is_enabled boolean
created_at string<date-time>
PUT /v1/automation-rules/{ruleId}

Update an automation rule

Updates an automation rule. All fields are optional; same validation rules as create apply to `action_config` and `trigger_config`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Automation rule identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no
description string no
trigger_type string no
trigger_config object no
action_type string no
action_config object no
is_enabled boolean no

Responses

StatusDescription
200 Automation rule updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — another rule with the same name already exists.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
trigger_type string
trigger_config object
action_type string
action_config object
is_enabled boolean
created_at string<date-time>
DELETE /v1/automation-rules/{ruleId}

Delete an automation rule

Permanently deletes an automation rule.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Automation rule identifier (UUIDv7).

Responses

StatusDescription
200 Automation rule deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/automation-rules/{ruleId}/execute

Manually execute an automation rule

Enqueues an immediate execution of the rule. The rule must belong to the caller's organization (cross-tenant IDOR prevention is enforced). Requires the `automation.manage` permission.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Automation rule identifier (UUIDv7).

Responses

StatusDescription
200 Rule execution enqueued.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `automation.manage` permission, or the rule does not belong to the caller's organization.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/automation-rules/{ruleId}/executions

List executions for an automation rule

Returns execution history for the specified automation rule. Supports optional `status` filter and `page`/`page_size` pagination.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Automation rule identifier (UUIDv7).
status query string no Filter by execution status (up to 50 characters).
page query integer no Page number (1-based, max 100,000).
page_size query integer no Results per page (1–200).

Responses

StatusDescription
200 Rule execution history.
400 `INVALID_ID_FORMAT` — `ruleId` is not a valid UUID; or `VALIDATION_ERROR` — query params are invalid.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/campaigns

List campaigns

Returns all campaigns for the authenticated organization. Supports optional `status` and `type` query filters.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
status query string (enum) no Filter by campaign status: `active` or `paused`.
type query string (enum) no Filter by campaign type.
limit query integer no Maximum number of records to return. Default and ceiling are endpoint-specific (commonly default 25–50, max 100).
offset query integer no Number of records to skip for offset pagination.

Responses

StatusDescription
200 Campaign list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
campaigns array of object
total_count integer
POST /v1/campaigns

Create a campaign

Creates a new campaign for the authenticated organization.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
description string no
campaign_type string (enum) dripsequenceone_shot yes
trigger object no Trigger configuration JSON.
is_active boolean no Whether the campaign is active. Defaults to `false`.
starts_at string<date-time> no
ends_at string<date-time> no
metadata object no

Responses

StatusDescription
201 Campaign created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
campaign_type string (enum) dripsequenceone_shot
status string (enum) activepaused
starts_at string | null
ends_at string | null
created_at string<date-time>
GET /v1/campaigns/{id}

Get a campaign

Returns a campaign by ID.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).

Responses

StatusDescription
200 Campaign record.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
campaign_type string (enum) dripsequenceone_shot
status string (enum) activepaused
starts_at string | null
ends_at string | null
created_at string<date-time>
PUT /v1/campaigns/{id}

Update a campaign

Updates campaign metadata. All fields are optional.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no
description string no
campaign_type string (enum) dripsequenceone_shot no
trigger object no
is_active boolean no
starts_at string<date-time> no
ends_at string<date-time> no
metadata object no

Responses

StatusDescription
200 Campaign updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
campaign_type string (enum) dripsequenceone_shot
status string (enum) activepaused
starts_at string | null
ends_at string | null
created_at string<date-time>
DELETE /v1/campaigns/{id}

Delete a campaign

Permanently deletes a campaign.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).

Responses

StatusDescription
200 Campaign deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/campaigns/{id}/enrollments

List enrollments for a campaign

Returns enrollments for the specified campaign, optionally filtered by `status`. Supports pagination via `limit`/`offset`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).
status query string (enum) no Filter by enrollment status.
limit query integer no Max records to return (1–100, default 25).
offset query integer no Zero-based offset for pagination.

Responses

StatusDescription
200 Enrollment list.
400 `INVALID_ID_FORMAT` — `id` is not a valid UUID; or `VALIDATION_ERROR` — query params are invalid.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
enrollments array of object
total_count integer
POST /v1/campaigns/{id}/enrollments

Enroll a user in a campaign

Enrolls a target user in the campaign. Requires the `campaign.enroll` permission.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
campaign_id string<uuid> yes
target_user_id string<uuid> yes User to enroll.
trigger_data object no
metadata object no

Responses

StatusDescription
201 User enrolled in campaign.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `campaign.enroll` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/campaigns/{id}/steps

List steps for a campaign

Returns all steps for the specified campaign, ordered by `step_number`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).

Responses

StatusDescription
200 Campaign step list.
400 `INVALID_ID_FORMAT` — `id` is not a valid UUID.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
steps array of object
total_count integer
POST /v1/campaigns/{id}/steps

Add a step to a campaign

Adds a step (email, notification, delay, condition, or action) to an existing campaign at the specified position (0-based, converted to 1-based `step_number` internally).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
campaign_id string<uuid> yes
name string yes
step_type string (enum) emailnotificationdelayconditionaction yes
position integer yes 0-based position. Converted to 1-based `step_number` internally.
config object no
delay_seconds integer no
template_id string<uuid> no
metadata object no

Responses

StatusDescription
201 Campaign step created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
campaign_id string<uuid>
name string
step_type string (enum) emailnotificationdelayconditionaction
position integer 0-based display order.
config object
delay_seconds integer
template_id string | null
PUT /v1/campaigns/{id}/steps/{stepId}

Update a campaign step

Updates one or more fields of an existing campaign step. At least one field must be provided.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).
stepId path string<uuid> yes Step identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no Step display name.
position integer no 0-based position in the step sequence (converted to 1-based `step_number` internally).
config object no Action configuration for the step.
delay_seconds integer no Delay before the step executes, in seconds (converted to `delay_minutes` internally).
template_id string<uuid> no Optional linked template identifier.
metadata object no Arbitrary metadata / conditions object.

Responses

StatusDescription
200 Campaign step updated.
400 `INVALID_ID_FORMAT` — `id` or `stepId` is not a valid UUID; or `VALIDATION_ERROR` — body is invalid.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
campaign_id string<uuid>
name string
step_type string (enum) emailnotificationdelayconditionaction
position integer 0-based display order.
config object
delay_seconds integer
template_id string | null
DELETE /v1/campaigns/{id}/steps/{stepId}

Delete a campaign step

Permanently removes a step from the campaign.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Campaign identifier (UUIDv7).
stepId path string<uuid> yes Step identifier (UUIDv7).

Responses

StatusDescription
200 Campaign step deleted. Returns `{ deleted: true }`.
400 `INVALID_ID_FORMAT` — `id` or `stepId` is not a valid UUID.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
deleted boolean
GET /v1/change-mgmt/approvals

List change approvals

Returns approval decisions, optionally filtered by `changeset_id` and/or `decision`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
changeset_id query string<uuid> no Filter by changeset identifier (UUIDv7).
decision query string (enum) no Filter by approval decision.
limit query integer no Maximum number of records to return. Default and ceiling are endpoint-specific (commonly default 25–50, max 100).
offset query integer no Number of records to skip for offset pagination.

Responses

StatusDescription
200 Approval list.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
approvals array of object
total_count integer
POST /v1/change-mgmt/approvals

Record a change approval decision

Records an approval, rejection, or change-request decision against a changeset.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
changeset_id string<uuid> yes
decision string (enum) approverejectrequest_changes yes
comment string no
conditions array of string no Optional list of conditions attached to this decision.

Responses

StatusDescription
201 Approval decision recorded.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/change-mgmt/changesets

List changesets

Returns changesets for the authenticated organization. Supports optional filters: `project_id`, `status`, `changeset_type`, `search`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
project_id query string<uuid> no Filter by project identifier (UUIDv7).
status query string (enum) no Filter by changeset status.
changeset_type query string (enum) no Filter by changeset type.
search query string no Free-text search across title/description (max 200 chars).
limit query integer no Maximum number of records to return. Default and ceiling are endpoint-specific (commonly default 25–50, max 100).
offset query integer no Number of records to skip for offset pagination.

Responses

StatusDescription
200 Changeset list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
changesets array of object
total_count integer
POST /v1/change-mgmt/changesets

Create a changeset

Creates a new changeset to group related changes before review and deployment.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
title string yes
description string no
project_id string<uuid> no
changeset_type string (enum) featurebugfixhotfixrefactorconfig no Defaults to `feature` when omitted.
priority string (enum) lownormalhighcritical no Defaults to `normal` when omitted.
metadata object no

Responses

StatusDescription
201 Changeset created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
title string
description string | null
project_id string | null
changeset_type string (enum) featurebugfixhotfixrefactorconfig
priority string (enum) lownormalhighcritical
status string Current lifecycle status.
changes array of object
created_at string<date-time>
GET /v1/change-mgmt/changesets/{id}

Get a changeset

Returns a changeset including its individual changes.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Changeset identifier (UUIDv7).

Responses

StatusDescription
200 Changeset record.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
title string
description string | null
project_id string | null
changeset_type string (enum) featurebugfixhotfixrefactorconfig
priority string (enum) lownormalhighcritical
status string Current lifecycle status.
changes array of object
created_at string<date-time>
PUT /v1/change-mgmt/changesets/{id}

Update a changeset

Updates changeset fields. The `status` field is **not accepted here** — use the dedicated lifecycle endpoints (`/submit`, `/approve`, `/reject`, `/apply`, `/revert`). Sending `status` returns `400 VALIDATION_ERROR` with a redirect hint.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Changeset identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
title string no
description string no
priority string (enum) lownormalhighcritical no
metadata object no

Responses

StatusDescription
200 Changeset updated.
400 `VALIDATION_ERROR` — field validation failed, or the request included `status` (use lifecycle endpoints instead).
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
title string
description string | null
project_id string | null
changeset_type string (enum) featurebugfixhotfixrefactorconfig
priority string (enum) lownormalhighcritical
status string Current lifecycle status.
changes array of object
created_at string<date-time>
GET /v1/change-mgmt/changesets/{id}/changes

List changes in a changeset

Returns all individual resource changes within the specified changeset.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Changeset identifier (UUIDv7).

Responses

StatusDescription
200 Change list.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
changes array of object
total_count integer
POST /v1/change-mgmt/changesets/{id}/changes

Add a change to a changeset

Adds an individual resource change to the specified changeset. `change_type` determines the recorded operation: `create` → INSERT, `update`/`move`/`rename` → UPDATE, `delete` → DELETE.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Changeset identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
change_type string (enum) createupdatedeletemoverename yes `create` → INSERT, `update`/`move`/`rename` → UPDATE, `delete` → DELETE.
resource_type string yes
resource_id string<uuid> no
before_state object no
after_state object no
diff object no
description string no
metadata object no

Responses

StatusDescription
201 Change added to changeset.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
changeset_id string<uuid>
change_type string (enum) createupdatedeletemoverename
resource_type string
resource_id string | null
before_state object | null
after_state object | null
diff object | null
description string | null
created_at string<date-time>
POST /v1/deployments/approval-policy

Set a deployment approval policy

Creates or replaces the approval policy for a deployment environment. The policy specifies which roles must approve a run to `production` or `preprod` and minimum approval quorums.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
environment string (enum) productionpreprod yes Target deployment environment.
role_keys array of string yes Role keys that are eligible approvers (1–32, each max 64 chars).
min_total_approvals integer no Minimum total approvals required (minimum 2). Optional.
min_roles_represented integer no Minimum distinct roles that must be represented in the approvals (minimum 2). Optional.

Responses

StatusDescription
200 Approval policy set.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/approvals

Approve or reject a deployment run

Records an approval or rejection decision for a pending deployment run. The `action` field determines the decision. Dual-approval rules (BB-03) are enforced by the stored procedure; a second approver in the same role is required for production deployments when the policy requires it.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
environment_id string<uuid> yes Deployment environment identifier.
commit_sha string yes Commit SHA being approved.
action string (enum) approvereject yes Approval decision.

Responses

StatusDescription
200 Approval or rejection recorded.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
409 `CONFLICT` — dual-approval requirement not yet satisfied; or another approval gate conflict.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/configs

Upsert a deployment config

Creates or updates a deployment configuration record. The config links a repository to the deployment system via vault and encryption key references.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
repo_id string<uuid> yes Repository identifier (UUIDv7).
vault_ref string yes Vault reference for secret injection.
dek_secret_ref string yes Data-encryption key secret reference.
webhook_secret_ref string no Optional webhook signing secret reference.
dek_epoch integer no Optional DEK epoch for key rotation tracking (min 1).

Responses

StatusDescription
200 Config created or updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/environments

Upsert a deployment environment

Creates or updates a deployment environment within a config. Environments define the branch, deploy commands, container size, and secret exposure.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
config_id string<uuid> yes Parent deployment config identifier.
name string yes Environment name (e.g. `production`, `staging`).
branch string yes Git branch to deploy from.
working_dir string no Optional working directory within the repository.
deploy_commands array of string no Ordered list of deploy commands to execute (max 64).
container_size string (enum) basicstandard-1standard-2standard-3standard-4 no Deploy container size.
exposed_secret_keys array of string no List of secret item UUIDs to inject as environment variables (max 128).
github_token_secret_ref string no Optional GitHub token secret reference for private repo access.
egress_allowlist array of string no Optional network egress allowlist (max 64 entries).
auto_deploy boolean no Whether to auto-trigger a deploy on branch push.

Responses

StatusDescription
200 Environment created or updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/runs

Start a deployment run

Creates a queued deployment run for the given environment and commit SHA, then best-effort provisions a deploy container. The run record is created regardless of container provisioning success. If provisioning fails, `orchestrated: false` is returned and the run can be retried. Requires the `deployment.trigger` permission.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
environment_id string<uuid> yes Deployment environment identifier.
commit_sha string yes Commit SHA to deploy.
trigger string (enum) manualwebhookpollerretry no What triggered this run. Optional.
instance_token_id string<uuid> no Optional pre-created instance token identifier.

Responses

StatusDescription
200 Run queued. `orchestrated: true` if the container was successfully started. If `orchestrated: false`, `orchestration_error` contains a non-fatal reason.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
409 `CONFLICT` — dual-approval gate not met; submit approvals first.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
run_id string<uuid>
orchestrated boolean `true` if the deploy container was successfully started.
orchestration_error string | null Non-fatal message if the container could not be started. The run record still exists and can be retried.
POST /v1/deployments/runs/{runId}/cancel

Cancel a deployment run

Cancels a queued or running deployment run.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
runId path string<uuid> yes Deployment run identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
reason string no Optional cancellation reason.

Responses

StatusDescription
200 Run cancelled.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/deployments/runs/{runId}/events

List deployment run events

Returns the progress/error log for a deployment run. Supports incremental polling via `?after_seq=` to fetch only events since the last poll.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
runId path string<uuid> yes Deployment run identifier (UUIDv7).
after_seq query string no Return only events with a sequence number greater than this value.

Responses

StatusDescription
200 Run event log.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/runs/{runId}/events

Record a deployment run event (container only)

Records a structured progress/status event for a deployment run. This endpoint is called **only** by the deploy container using its per-run instance token (`apiKeyAuth`). A human session JWT is rejected. When the container reports a terminal status (`succeeded`, `failed`, or `cancelled`), the instance token is revoked automatically.

Auth API key (Bearer bb_live_…)

Parameters

NameInTypeRequiredDescription
runId path string<uuid> yes Deployment run identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
client_event_id string yes Client-generated idempotency key for this event.
level string (enum) infowarnerror no Log level. Optional.
phase string no Deployment phase (e.g. `checkout`, `build`, `deploy`). Optional.
error_class string no Error class or type for error-level events. Optional.
sqlstate string no 5-char PostgreSQL SQLSTATE code for DB errors. Optional.
failing_migration string no Migration filename that triggered the failure. Optional.
wrangler_binding string no Cloudflare wrangler binding name involved in a failure. Optional.
message string no Event message. Optional.
status string (enum) queuedprovisioningrunningsucceededfailedcancelled no Overall run status at the time of this event. Terminal statuses (`succeeded`, `failed`, `cancelled`) revoke the instance token. Optional.

Responses

StatusDescription
200 Event recorded.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — the token is not a valid deployment instance token or is not bound to this run.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/runs/{runId}/retry

Retry a deployment run

Retries a failed or cancelled deployment run.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
runId path string<uuid> yes Deployment run identifier (UUIDv7).

Responses

StatusDescription
200 Run retry queued.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/deployments/secret-keys

List secret keys available to this run (container only)

Returns the list of escrow secret item IDs that the running deploy container is authorized to fetch. This endpoint requires a deployment instance token (`apiKeyAuth`); a user JWT is rejected. Use the returned IDs with `POST /v1/deployments/secret-value` to retrieve decrypted values.

Auth API key (Bearer bb_live_…)

Responses

StatusDescription
200 List of authorized secret item IDs.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller is not a deployment instance token.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/secret-value

Get a decrypted secret value (container only)

Authorizes and returns the decrypted plaintext value of the specified secret item. This endpoint requires a deployment instance token (`apiKeyAuth`); a user JWT is rejected. The value is decrypted in the API worker — never in the database — and returned over TLS. The container is expected to hold values in memory only.

Auth API key (Bearer bb_live_…)

Request Body

FieldTypeRequiredDescription
item_id string<uuid> yes Escrow secret item identifier (UUIDv7).

Responses

StatusDescription
200 Decrypted secret value.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller is not a deployment instance token, or is not authorized to access this secret for this run.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
name string | null Secret name.
value string Decrypted plaintext value.
GET /v1/deployments/setup

Get deployment setup

Returns the deployment configuration for the authenticated organization (configs, environments, approval policies, and run summary). Pass `config_id` to scope the response to a single configuration.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
config_id query string<uuid> no Deployment config identifier (UUIDv7) to filter the response.

Responses

StatusDescription
200 Deployment setup record.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/deployments/solo-mode

Set solo-operator mode

Enables or disables solo-operator mode for a deployment config. In solo mode a single-person organization can deploy without a second approver.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
config_id string<uuid> yes Deployment config identifier.
enabled boolean no Whether to enable solo-operator mode. Optional; SP applies its own default when omitted.

Responses

StatusDescription
200 Solo-operator mode updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/feature-flags/effective

Get effective feature flags for caller

Returns the effective (resolved) feature flag state for the authenticated user and their organization. Available to any authenticated user; does not require super-admin.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Resolved feature flag states for the caller's organization.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
org_id string<uuid>
feature_flags object Resolved feature flag state map.
GET /v1/releases/{slug}/current

Get the current release version (public)

Returns the latest published version for the product and channel visible to the given organization. This is the update-check endpoint called by installed desktop clients. No authentication is required; `org_id` must be supplied as a query parameter to scope the lookup.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
slug path string yes Product slug.
org_id query string<uuid> yes Organization identifier (UUIDv7) — required because no session is present.
channel query string no Distribution channel (1–50 chars). Defaults to the product's primary channel when omitted.
current_version query string no The client's installed version string. Included in telemetry; does not change the response.
install_id_hash query string no Pseudonymous install ID hash (≤256 chars) for analytics. Never linked to a user.

Responses

StatusDescription
200 Current release version record.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
version string
channel string
release_notes_url string | null
required_upgrade boolean
artefacts array of object
manifest_sha256_hex string
published_at string<date-time>
PUT /v1/releases/products/{slug}

Upsert a release product

Creates or updates a desktop release product definition for the authenticated organization. A product groups versions across channels for a single distributable tool.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
slug path string yes Product slug (lowercase alphanumeric with dots, hyphens, or underscores; 1–100 chars).

Request Body

FieldTypeRequiredDescription
base_tool string yes Base tool identifier for this product.
display_name string yes Human-readable product name.
branding_config_id string<uuid> no Optional branding config identifier.
custom_domain string no Optional custom domain for release downloads (max 253 chars).
data_residency string (enum) useu no Data residency region for release artefacts. Optional.

Responses

StatusDescription
200 Product created or updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.manage` permission.
409 `CONFLICT` — the custom domain is already taken by another product.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
slug string Product slug.
org_id string<uuid>
base_tool string
display_name string
branding_config_id string | null
custom_domain string | null
data_residency string (enum) useu
created_at string<date-time>
POST /v1/releases/products/{slug}/channels/{channel}/promote

Promote a version to a channel

Promotes the specified version to the target channel (e.g. promoting from `beta` to `stable`). The specified version string must already be finalized.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
slug path string yes Product slug.
channel path string yes Source channel to promote from (e.g. `beta`, `nightly`). Alphanumeric with dots/hyphens/underscores.

Request Body

FieldTypeRequiredDescription
version string yes Version string to promote.
target_channel string yes Destination channel (e.g. `stable`).

Responses

StatusDescription
200 Version promoted to the target channel.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — the target channel already has this version or a newer one.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/releases/products/{slug}/versions

Start a release version publish

Opens a new version staging record for the product. Call this before uploading artefacts. Returns the staging version ID used for subsequent `/artefacts`, `/complete`, and `/finalize` calls.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
slug path string yes Product slug.

Request Body

FieldTypeRequiredDescription
version string yes Version string (e.g. `1.2.3`).
channel string no Distribution channel (e.g. `stable`, `beta`, `nightly`). Optional.
publisher_token_hash_hex string no Hex-encoded hash of the publisher token for this publish flow. Optional.

Responses

StatusDescription
201 Staging version created. Returns the staging release record including the version ID.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 `NOT_FOUND` — product slug not found.
409 `CONFLICT` — a version with this version string already exists for the product.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
product_slug string
version string
channel string
state string (enum) stagingcompletefinalizedyanked
created_at string<date-time>
POST /v1/releases/signing-keys

Register a signing key

Registers an Ed25519 public signing key for the organization's release pipeline. The key is identified by `key_id` (human-readable); `public_key_hex` is the 32-byte raw Ed25519 public key as 64 hex chars. Optionally chains from a prior key via `signed_by_key_id` and `successor_signature_hex`.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
key_id string yes Human-readable key identifier (e.g. `prod-2025-01`).
public_key_hex string yes Hex-encoded 32-byte Ed25519 public key (exactly 64 hex chars).
signed_by_key_id string no Optional key_id of the predecessor key that signs the succession.
successor_signature_hex string no Optional hex-encoded 64-byte Ed25519 signature of this key's public_key_hex by the `signed_by_key_id` key (exactly 128 hex chars).

Responses

StatusDescription
201 Signing key registered.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.manage_keys` permission.
409 `CONFLICT` — a key with this `key_id` already exists.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
key_id string
org_id string<uuid>
public_key_hex string
is_active boolean
revoked_at string | null
signed_by_key_id string | null
successor_signature_hex string | null
created_at string<date-time>
POST /v1/releases/signing-keys/{id}/revoke

Revoke a signing key

Revokes the signing key identified by `id` (the textual `key_id`, not a UUID). Revoked keys are retained for historical verification but are excluded from the active key chain.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string yes The signing key's textual `key_id` (1–200 chars, not a UUID).

Request Body

FieldTypeRequiredDescription
reason string yes Mandatory reason for revocation (audit trail).

Responses

StatusDescription
200 Signing key revoked.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.manage_keys` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — the key is already revoked.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/releases/signing-keys/chain

Get the signing key chain (public)

Returns the full chain of active and revoked public signing keys for the organization. Clients use this to verify the integrity and authenticity of release manifests. No authentication is required; `org_id` must be supplied as a query parameter.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
org_id query string<uuid> yes Organization identifier (UUIDv7).

Responses

StatusDescription
200 Signing key chain.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
DELETE /v1/releases/versions/{id}

Cancel a staged release version

Cancels and removes a staged (not-yet-finalized) release version. Returns `VALIDATION_ERROR` if the version has already been finalized.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Staged release version identifier (UUIDv7).

Responses

StatusDescription
200 Staged version cancelled.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — the version is already finalized and cannot be cancelled.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/releases/versions/{id}/artefacts

Add an artefact to a staged version

Registers a platform-specific binary artefact (OS + arch combination) against a staged release version. The artefact must have already been uploaded to R2; this call records its `r2_key`, `sha256_hex`, and optional platform-signed digest.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Staged release version identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
os string yes Target operating system (e.g. `linux`, `darwin`, `windows`).
arch string yes Target CPU architecture (e.g. `x86_64`, `aarch64`).
r2_key string yes R2 object key where the binary was uploaded.
archive_format string yes Archive format (e.g. `zip`, `tar.gz`).
sha256_hex string yes Lowercase hex-encoded SHA-256 of the artefact binary (exactly 64 chars).
size_bytes integer yes Artefact file size in bytes.
os_signature object no Optional OS-level code-signing signature object (structure is OS-dependent).

Responses

StatusDescription
200 Artefact registered.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — the staging version is in an invalid state (e.g. already finalized or yanked).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/releases/versions/{id}/complete

Complete a staged version

Marks the artefact upload phase as complete, records optional release notes URL, minimum OS requirements, and whether this is a forced upgrade.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Staged release version identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
release_notes_url string<uri> no URL to the release notes page (max 2048 chars).
min_supported_os object no Minimum OS version map (e.g. `{windows: '10', macos: '12.0'}`).
required_upgrade boolean no Whether this is a forced upgrade. Clients below this version will be blocked.

Responses

StatusDescription
200 Version marked complete.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — no artefacts have been registered or the version state is invalid.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/releases/versions/{id}/finalize

Finalize a staged version

Finalizes the staged version by recording the manifest SHA-256 hash and an Ed25519 signature over the manifest. The version is published and becomes visible to update checks after this call.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Staged release version identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
manifest_sha256_hex string yes Hex-encoded SHA-256 of the release manifest (exactly 64 chars).
manifest_sig_hex string yes Hex-encoded Ed25519 signature over the manifest hash (exactly 128 chars / 64 bytes).

Responses

StatusDescription
200 Version finalized and published.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — the version is not in the `complete` state, or the active signing key is missing.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PATCH /v1/releases/versions/{id}/rollout

Set rollout percentage for a version

Sets the rollout percentage for a published version. A percentage of `0` pauses rollout; `100` completes it. Requires both `product_slug` and `version` in the body.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Release version surrogate identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
product_slug string yes Product slug.
version string yes Version string.
percentage integer yes Rollout percentage. `0` pauses rollout; `100` completes it.

Responses

StatusDescription
200 Rollout percentage updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.publish` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — the version has been yanked.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/releases/versions/{id}/yank

Yank a release version

Yanks a published version so that update checks no longer offer it to clients. Requires both `product_slug` and `version` in the body alongside the path `id`. A reason is mandatory for audit purposes.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Release version surrogate identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
product_slug string yes Product slug to identify the release.
version string yes Version string to yank.
reason string yes Mandatory reason for yanking (audit trail).

Responses

StatusDescription
200 Version yanked.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `releases.yank` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — the version is already yanked.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/saas-packages/{packageId}/approval-policies

Get approval policies

Returns all approval policies for the SaaS package.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).

Responses

StatusDescription
200 List of approval policies.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/approval-policies

Create an approval policy

Creates an approval policy for the SaaS package. The `rules` field must be a top-level branch node (`{operator, conditions}`) — bare leaf conditions at the top level are rejected. The conditions tree is limited to 5 levels of nesting. The request body is limited to 8 KiB to guard against deeply-nested rule trees.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
category string (enum) staging_promotionpreprod_promotionproduction_deploymentsecurity_reviewcompliance_reviewrollback_authorization yes Policy category.
name string yes Policy name.
description string no Optional policy description.
rules any yes A node in the approval condition tree. The top-level `rules` field must be a branch node (`operator` + `conditions`). Leaf nodes specify a specific_users, role, group, or cross_role condition. Maximum tree depth is 5; each branch may have 1–10 children.

Responses

StatusDescription
201 Approval policy created.
400 `INVALID_JSON`, `VALIDATION_ERROR` (field validation or rules tree exceeds depth limit), or `PAYLOAD_TOO_LARGE` (body > 8 KiB).
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `approval_policy.create` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — a policy with this category is already active for the package.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
package_id string<uuid>
category string (enum) staging_promotionpreprod_promotionproduction_deploymentsecurity_reviewcompliance_reviewrollback_authorization
name string
description string | null
rules any A node in the approval condition tree. The top-level `rules` field must be a branch node (`operator` + `conditions`). Leaf nodes specify a specific_users, role, group, or cross_role condition. Maximum tree depth is 5; each branch may have 1–10 children.
is_active boolean
created_at string<date-time>
updated_at string<date-time>
DELETE /v1/saas-packages/{packageId}/approval-policies/{policyId}

Deactivate an approval policy

Soft-deactivates an approval policy. A deactivated policy is no longer enforced for new approval requests.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
policyId path string<uuid> yes Approval policy identifier (UUIDv7).

Responses

StatusDescription
200 Policy deactivated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `approval_policy.delete` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — policy is currently in use by a pending approval and cannot be deactivated.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/saas-packages/{packageId}/environments

Get environment deployment status

Returns the currently deployed release for each environment (development, staging, preprod, production) for the given SaaS package.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).

Responses

StatusDescription
200 Per-environment deployment status.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/saas-packages/{packageId}/environments/history

Get deployment history

Returns the paginated deployment history for a SaaS package, optionally filtered by environment.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
environment query string (enum) no Filter by environment.
page query integer no 1-based page number.
limit query integer no Records per page (1–100).

Responses

StatusDescription
200 Paginated deployment history.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/saas-packages/{packageId}/releases

List releases

Returns paginated releases for a SaaS package, optionally filtered by status.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
status query string (enum) no Filter by release status.
page query integer no 1-based page number (default 1).
limit query integer no Records per page (1–100).

Responses

StatusDescription
200 Paginated list of releases.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/releases

Create a release

Creates a new draft release for the given SaaS package. The release name must be unique within the package. Returns the full release record.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
release_name string yes Human-readable release name, unique within the package.
release_notes string no Optional markdown release notes.

Responses

StatusDescription
201 Release created. The full release record is returned under `data`.
400 `INVALID_JSON` or `VALIDATION_ERROR` (name missing, exceeds 200 chars, or invalid package ID) or `INVALID_ID_FORMAT` (malformed packageId).
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.create` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid> Release identifier (UUIDv7).
package_id string<uuid> Owning SaaS package identifier.
release_name string Human-readable release name.
release_notes string | null Optional markdown release notes.
status string (enum) drafttestingapprovedrejectedarchived Current lifecycle status.
created_at string<date-time>
updated_at string<date-time>
GET /v1/saas-packages/{packageId}/releases/{releaseId}

Get a release

Returns a single release record by ID.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Responses

StatusDescription
200 Release record.
400 `INVALID_ID_FORMAT` — malformed packageId or releaseId.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid> Release identifier (UUIDv7).
package_id string<uuid> Owning SaaS package identifier.
release_name string Human-readable release name.
release_notes string | null Optional markdown release notes.
status string (enum) drafttestingapprovedrejectedarchived Current lifecycle status.
created_at string<date-time>
updated_at string<date-time>
GET /v1/saas-packages/{packageId}/releases/{releaseId}/approval-status

Evaluate approval policy status

Evaluates the current approval policy for the release and environment, returning whether approval requirements are satisfied, the individual approver decisions, and which approvers are still outstanding.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).
environment query string (enum) yes Environment to evaluate approval for.

Responses

StatusDescription
200 Approval policy evaluation result.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
approved boolean
pending_conditions array of string
approvers array of object
POST /v1/saas-packages/{packageId}/releases/{releaseId}/approve

Approve a release

Records an approval decision for the release targeting the specified environment. Separation-of-duties is enforced: the approver must not be the requester (when the package policy requires it).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) stagingpreprodproduction yes Target environment being approved.
comment string no Optional approval comment.

Responses

StatusDescription
200 Approval recorded.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.approve` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — separation-of-duties violation, wrong release state, or no active approval request.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/saas-packages/{packageId}/releases/{releaseId}/comments

List release comments

Returns paginated comments for a release, optionally filtered by environment or comment type.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).
environment query string (enum) no Filter by environment.
comment_type query string (enum) no Filter by comment type.
page query integer no 1-based page number.
limit query integer no Records per page (1–100).

Responses

StatusDescription
200 Paginated comment list.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/releases/{releaseId}/comments

Create a release comment

Adds a comment to a release. Comments can be threaded via `parent_comment_id` and scoped to a specific environment.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
content string yes Comment content (markdown).
comment_type string (enum) generalbugtest_passtest_failapprovalrejectiontask no Optional comment category.
environment string (enum) developmentstagingpreprodproduction no Optional environment context for the comment.
parent_comment_id string<uuid> no Optional parent comment ID for threaded replies.

Responses

StatusDescription
201 Comment created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.comment` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
release_id string<uuid>
author_id string<uuid>
content string
comment_type string
environment string | null
parent_comment_id string | null
created_at string<date-time>
POST /v1/saas-packages/{packageId}/releases/{releaseId}/compliance-check

Run a compliance check

Evaluates the release against compliance requirements for the target environment (approval status, mandatory tests, change-window restrictions, etc.). Returns a structured compliance result indicating pass/fail per check.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
target_environment string (enum) stagingpreprodproduction yes Environment to evaluate compliance for.

Responses

StatusDescription
200 Compliance check result.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.compliance` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/releases/{releaseId}/deploy

Deploy a release

Deploys the release to the specified environment. Supports four rollout strategies: `immediate` (all tenants at once), `targeted` (explicit list of org IDs), `percentage` (a random sample), and `progressive` (staged percentage ramp-up with configurable wait periods). A progressive deploy with `rollout_stages` starts the rollout scheduler automatically. Invalidates the application-config KV cache on success.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) developmentstagingpreprodproduction yes Target deployment environment.
notes string no Optional deployment notes.
rollout_strategy string (enum) immediatetargetedpercentageprogressive no Rollout strategy. Defaults to `immediate` when omitted.
target_org_ids array of string no Specific organization IDs for `targeted` strategy.
target_percentage integer no Rollout percentage for the `percentage` strategy.
rollout_stages array of object no Stage definitions for `progressive` strategy (1–20).

Responses

StatusDescription
200 Deployment initiated. Returns the deployment record. If a `progressive` strategy was requested, `rollout_plan_id` is included.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.deploy` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — an active deployment already exists for this environment, or the release is in an invalid state for deployment.
422 `VALIDATION_ERROR` — the release cannot be deployed (e.g. approval required, compliance check required, or rejection in place).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
deployment_id string<uuid>
environment string
status string
deployed_at string | null
POST /v1/saas-packages/{packageId}/releases/{releaseId}/import-to-draft

Import a release to draft

Imports the specified release's configuration into a new draft for the package. Used to create a new release pre-populated from an existing one (e.g. to re-apply a deployed config as a baseline for new changes).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier to import (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) developmentstagingpreprodproduction yes Source environment to import the current deployment state from.

Responses

StatusDescription
200 Import completed. Returns the new draft release.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.import` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid> Release identifier (UUIDv7).
package_id string<uuid> Owning SaaS package identifier.
release_name string Human-readable release name.
release_notes string | null Optional markdown release notes.
status string (enum) drafttestingapprovedrejectedarchived Current lifecycle status.
created_at string<date-time>
updated_at string<date-time>
GET /v1/saas-packages/{packageId}/releases/{releaseId}/items

List release manifest items

Returns the version-pinned manifest items for the release. Each item represents a configuration artifact (screen, seed, connector, etc.) pinned at a specific version in this release snapshot.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Responses

StatusDescription
200 Release manifest items.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/releases/{releaseId}/reject

Reject a release

Records a rejection decision for a pending approval. The `reason` field is required for audit purposes.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) stagingpreprodproduction yes Target environment being rejected.
reason string yes Mandatory rejection reason.

Responses

StatusDescription
200 Rejection recorded.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.approve` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — no active approval request to reject, or wrong release state.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/releases/{releaseId}/request-approval

Request approval for a release

Submits an approval request for the release targeting the specified environment. Requires an active approval policy to exist for the target environment category; if none exists, returns `409 CONFLICT`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) stagingpreprodproduction yes Target environment for which approval is requested.

Responses

StatusDescription
200 Approval request submitted. Returns the approval request record.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.update` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — no active approval policy exists for the target environment category.
422 `VALIDATION_ERROR` — the release is not in a state from which approval can be requested.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/releases/{releaseId}/rollback

Rollback a release

Rolls back the active deployment in the specified environment to the previously deployed release. Only `staging`, `preprod`, and `production` environments support rollback.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) stagingpreprodproduction yes Target environment to roll back.
notes string no Optional rollback notes.

Responses

StatusDescription
200 Rollback initiated. Returns the new deployment record.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.rollback` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — no prior deployment exists to roll back to, or the transition is otherwise invalid.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
deployment_id string<uuid>
environment string
status string
deployed_at string | null
PATCH /v1/saas-packages/{packageId}/releases/{releaseId}/status

Update release status

Transitions the release to the specified status. Valid transitions are enforced server-side; an invalid transition returns `422 VALIDATION_ERROR`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
status string (enum) testingapprovedrejectedarchived yes Target status. `draft` is omitted because you cannot manually transition back to draft.
reason string no Optional reason for the transition (required for `rejected` by convention).

Responses

StatusDescription
200 Release status updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — the requested status transition is invalid for the release's current state (e.g. transition preconditions not met).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid> Release identifier (UUIDv7).
package_id string<uuid> Owning SaaS package identifier.
release_name string Human-readable release name.
release_notes string | null Optional markdown release notes.
status string (enum) drafttestingapprovedrejectedarchived Current lifecycle status.
created_at string<date-time>
updated_at string<date-time>
POST /v1/saas-packages/{packageId}/releases/{releaseId}/undeploy

Undeploy a release

Removes the current deployment from the specified environment, leaving the environment with no active release. Only `staging`, `preprod`, and `production` environments are supported.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
releaseId path string<uuid> yes Release identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
environment string (enum) stagingpreprodproduction yes Target environment to undeploy from.
notes string no Optional undeploy notes.

Responses

StatusDescription
200 Release undeployed.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.deploy` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — no active deployment in the requested environment.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/saas-packages/{packageId}/releases/diff

Diff two releases

Returns a semantic diff of the version-pinned manifest between two releases of the same package. Both `from` and `to` must be UUIDs of releases that belong to this package.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
from query string<uuid> yes Release ID to diff from (UUIDv7).
to query string<uuid> yes Release ID to diff to (UUIDv7).

Responses

StatusDescription
200 Diff result.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/rollouts

Create a rollout plan

Creates a rollout plan for an existing active deployment. The plan defines how the release is progressively distributed across tenants. Requires `saas_release.deploy` permission.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
deployment_id string<uuid> yes Deployment identifier to roll out.
strategy string (enum) immediatetargetedpercentageprogressive yes Rollout strategy.
target_org_ids array of string no Specific organizations for `targeted` strategy (max 1000).
stages array of object no Stage definitions for `progressive` strategy (max 20).

Responses

StatusDescription
201 Rollout plan created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.deploy` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — a rollout plan already exists for this deployment.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
deployment_id string<uuid>
strategy string (enum) immediatetargetedpercentageprogressive
current_stage integer
status string
stages array of object
created_at string<date-time>
GET /v1/saas-packages/{packageId}/rollouts/{rolloutId}

Get rollout status

Returns the current rollout plan status including per-stage progress.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
rolloutId path string<uuid> yes Rollout plan identifier (UUIDv7).

Responses

StatusDescription
200 Rollout plan with per-stage progress.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
deployment_id string<uuid>
strategy string (enum) immediatetargetedpercentageprogressive
current_stage integer
status string
stages array of object
created_at string<date-time>
POST /v1/saas-packages/{packageId}/rollouts/{rolloutId}/advance

Advance rollout to next stage

Manually advances a progressive rollout to the next stage without waiting for the scheduled wait period to expire.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
rolloutId path string<uuid> yes Rollout plan identifier (UUIDv7).

Responses

StatusDescription
200 Rollout advanced to the next stage.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.deploy` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
422 `VALIDATION_ERROR` — rollout is not in a state that can be advanced (e.g. already complete or cancelled).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/rollouts/{rolloutId}/cancel

Cancel a rollout

Cancels a progressive rollout. The rollout is terminated and no further stages will be executed. An optional `reason` can be provided.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
rolloutId path string<uuid> yes Rollout plan identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
reason string no Optional reason for the rollout action (pause, resume, cancel).

Responses

StatusDescription
200 Rollout cancelled.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.deploy` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/saas-packages/{packageId}/rollouts/{rolloutId}/pause

Pause a rollout

Pauses a progressive rollout at the current stage. An optional `reason` can be provided. The rollout can be resumed by advancing to the next stage.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
packageId path string<uuid> yes SaaS package identifier (UUIDv7).
rolloutId path string<uuid> yes Rollout plan identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
reason string no Optional reason for the rollout action (pause, resume, cancel).

Responses

StatusDescription
200 Rollout paused.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `FORBIDDEN` — caller lacks the `saas_release.deploy` permission.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/time-triggers

List time triggers

Returns time-based automation triggers for the authenticated organization.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
page query integer no Page number (1-based).
page_size query integer no Results per page (max 200).

Responses

StatusDescription
200 Time trigger list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
triggers array of object
total_count integer
POST /v1/time-triggers

Create a time trigger

Creates a cron-based time trigger. The `cron_expression` must be a valid 5-field cron expression (minute hour day-of-month month day-of-week).

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
cron_expression string yes Valid 5-field cron expression.
action_type string yes
action_config object yes
is_enabled boolean no
next_run_at string<date-time> no

Responses

StatusDescription
201 Time trigger created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
cron_expression string 5-field cron expression (minute hour day-of-month month day-of-week).
action_type string
action_config object
is_enabled boolean
next_run_at string | null
created_at string<date-time>
PUT /v1/time-triggers/{id}

Update a time trigger

Updates a time trigger. All fields are optional.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Time trigger identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no
cron_expression string no Valid 5-field cron expression.
action_type string no
action_config object no
is_enabled boolean no
next_run_at string<date-time> no

Responses

StatusDescription
200 Time trigger updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
cron_expression string 5-field cron expression (minute hour day-of-month month day-of-week).
action_type string
action_config object
is_enabled boolean
next_run_at string | null
created_at string<date-time>
DELETE /v1/time-triggers/{id}

Delete a time trigger

Permanently deletes a time trigger.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Time trigger identifier (UUIDv7).

Responses

StatusDescription
200 Time trigger deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/time-triggers/{id}/logs

Get time trigger execution log

Returns execution logs for the specified time trigger with optional `status` filter and pagination.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
id path string<uuid> yes Time trigger identifier (UUIDv7).
status query string no Filter by execution status (max 50 chars).
page query integer no Page number (1-based).
page_size query integer no Results per page (max 200).

Responses

StatusDescription
200 Trigger execution log.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
logs array of object
total_count integer
GET /v1/workflows

List approval workflows

Returns approval workflows for the authenticated organization. When called via the `/v1/org/{orgId}/workflows` or `/v1/organizations/{orgId}/workflows` alias paths, `data` is a plain array rather than the paginated `{workflows, total_count}` object.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
status query string (enum) no Filter by workflow status.
trigger_type query string (enum) no Filter by trigger type.
search query string no Free-text search (max 200 chars).
limit query integer no Maximum number of records to return. Default and ceiling are endpoint-specific (commonly default 25–50, max 100).
offset query integer no Number of records to skip for offset pagination.

Responses

StatusDescription
200 Workflow list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
workflows array of object
total_count integer
POST /v1/workflows

Create an approval workflow

Creates a new approval workflow with up to 100 steps (each step defines a state transition and the role required to execute it).

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
description string no
entity_type_id string<uuid> no
status string (enum) activedraftarchived no
trigger_type string (enum) manualeventschedulewebhookcondition no
steps array of object no Up to 100 steps can be provided at creation time.

Responses

StatusDescription
201 Workflow created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
entity_type_id string | null
status string (enum) activedraftarchived
trigger_type string (enum) manualeventschedulewebhookcondition
steps array of object
created_at string<date-time>
GET /v1/workflows/{workflowId}

Get an approval workflow

Returns a single approval workflow including its steps.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
workflowId path string<uuid> yes Workflow identifier (UUIDv7).

Responses

StatusDescription
200 Workflow record.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
entity_type_id string | null
status string (enum) activedraftarchived
trigger_type string (enum) manualeventschedulewebhookcondition
steps array of object
created_at string<date-time>
PUT /v1/workflows/{workflowId}

Update an approval workflow

Updates workflow metadata. At least one non-`changelog` field must be provided. `changelog` alone is insufficient and returns 400.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
workflowId path string<uuid> yes Workflow identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no
description string no
entity_type_id string | null no
is_active boolean no
status string (enum) activedraftarchived no
trigger_type string (enum) manualeventschedulewebhookcondition no
changelog string no Optional change summary for audit purposes only (max 500 chars). Not a substitute for a data-field update.

Responses

StatusDescription
200 Workflow updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
entity_type_id string | null
status string (enum) activedraftarchived
trigger_type string (enum) manualeventschedulewebhookcondition
steps array of object
created_at string<date-time>
DELETE /v1/workflows/{workflowId}

Delete an approval workflow

Permanently deletes an approval workflow.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
workflowId path string<uuid> yes Workflow identifier (UUIDv7).

Responses

StatusDescription
200 Workflow deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/workflows/{workflowId}/steps

Add a step to a workflow

Adds a state-transition step to the workflow. Each step defines `from_state_id`, `to_state_id`, and the `required_role` that can execute the transition.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
workflowId path string<uuid> yes Workflow identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
from_state_id string<uuid> yes Source workflow state.
to_state_id string<uuid> yes Target workflow state.
required_role string no Role required to execute this transition.
required_group_id string<uuid> no Optional group required to execute this transition.

Responses

StatusDescription
201 Workflow step added.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
workflow_id string<uuid>
from_state_id string<uuid>
to_state_id string<uuid>
required_role string | null
required_group_id string | null
sort_order integer
PUT /v1/workflows/{workflowId}/steps/{stepId}

Update a workflow step

Updates a workflow step. At least one non-`changelog` field must be provided.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
workflowId path string<uuid> yes Workflow identifier (UUIDv7).
stepId path string<uuid> yes Step identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
from_state_id string<uuid> no
to_state_id string<uuid> no
required_role string | null no
required_group_id string | null no
sort_order integer no
changelog string no Optional change summary for audit purposes only (max 500 chars).

Responses

StatusDescription
200 Workflow step updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
workflow_id string<uuid>
from_state_id string<uuid>
to_state_id string<uuid>
required_role string | null
required_group_id string | null
sort_order integer
DELETE /v1/workflows/{workflowId}/steps/{stepId}

Delete a workflow step

Removes a state-transition step from the workflow.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
workflowId path string<uuid> yes Workflow identifier (UUIDv7).
stepId path string<uuid> yes Step identifier (UUIDv7).

Responses

StatusDescription
200 Workflow step deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/workflows/states

List workflow states

Returns all workflow states for the authenticated organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Workflow state list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/workflows/states

Create a workflow state

Creates a new workflow state. `color` must be a valid 7-char hex color (e.g. `#4CAF50`). `position` is 0-based display order.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
description string no
color string no 7-char hex color code (e.g. `#4CAF50`). Optional.
position integer no 0-based display order. Optional.
is_initial boolean no
is_terminal boolean no
metadata object no

Responses

StatusDescription
201 Workflow state created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
name string
description string | null
color string 7-char hex color code.
position integer
is_initial boolean
is_terminal boolean
metadata object | null
created_at string<date-time>