Appearance
Scenarios
Scenarios (called "plans" in the data model) are sandboxed copies of your live workforce data. This page covers the REST endpoints for creating, editing, submitting for approval, merging and archiving them. For the conceptual workflow, see Scenarios workflow.
New to Flowstate?
Read Live data vs scenarios first — scenarios are the foundation of every "what-if" workflow in Flowstate.
Plan Object
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (CUID format). System-generated. Read-only. |
title | string | Display name. |
description | string | null | Optional context. |
status | string | One of DRAFT, PENDING_APPROVAL, ACTIVE, REJECTED, ARCHIVED. |
createdAt | datetime (ISO 8601) | When the scenario was created. Read-only. |
createdByUserId | string | The user who created the scenario. Read-only. |
submittedAt | datetime | null | When the scenario was submitted for approval. Read-only. |
submittedByUserId | string | null | The user who submitted it. Read-only. |
rejectedAt | datetime | null | When the scenario was rejected. Read-only. |
rejectedByUserId | string | null | The user who rejected it. Read-only. |
rejectionReason | string | null | The reason given for rejection. |
assignees | array | Users assigned to review and approve. |
mergedAt | datetime | null | When the scenario was merged. Read-only. |
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /org/:orgId/scenarios | List scenarios |
GET | /org/:orgId/scenarios/:id | Get scenario |
POST | /org/:orgId/scenarios | Create scenario |
PATCH | /org/:orgId/scenarios/:id | Update scenario |
POST | /org/:orgId/scenarios/:id/submit | Submit for approval |
POST | /org/:orgId/scenarios/:id/approve | Approve a pending scenario |
POST | /org/:orgId/scenarios/:id/reject | Reject a pending scenario |
POST | /org/:orgId/scenarios/:id/merge | Merge an approved scenario into live data |
POST | /org/:orgId/scenarios/:id/revert | Discard all overlays on a scenario |
POST | /org/:orgId/scenarios/:id/archive | Archive a scenario |
DELETE | /org/:orgId/scenarios/:id | Delete a scenario |
POST | /org/:orgId/scenarios/:id/changes/remove | Remove a single change overlay |
List scenarios
GET /org/:orgId/scenariosQuery parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number. |
limit | integer | 20 | Records per page. Max 100. |
status | string | -- | Filter by status. Comma-separated for multiple. |
includeArchived | boolean | false | Whether to include archived scenarios. |
createdByMe | boolean | -- | Limit to scenarios you created. |
sortBy | string | updatedAt | One of updatedAt, createdAt, title. |
sortDir | string | desc | asc or desc. |
Example
bash
curl -X GET "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/scenarios?status=PENDING_APPROVAL" \
-H "Authorization: Bearer private_..."Create a scenario
POST /org/:orgId/scenariosRequest body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Display name. |
description | string | No | Optional context. |
forkFromScenarioId | string | No | If set, fork from this scenario. Otherwise fork from live data. |
Example
bash
curl -X POST "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/scenarios" \
-H "Authorization: Bearer private_..." \
-H "Content-Type: application/json" \
-d '{
"title": "Q3 hiring plan",
"description": "Adds 12 vacancies across Platform and Payments"
}'Submit for approval
POST /org/:orgId/scenarios/:id/submitMoves the scenario from DRAFT to PENDING_APPROVAL and notifies assignees.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
assigneeUserIds | string[] | Yes | Users who should approve. Must contain at least one user other than the submitter. |
note | string | No | Optional note for assignees. |
Approve a scenario
POST /org/:orgId/scenarios/:id/approveMoves the scenario from PENDING_APPROVAL to ACTIVE. The caller must be in the scenario's assignee list.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
comment | string | No | Optional comment recorded with the approval. |
WARNING
You cannot approve your own scenario. The server enforces this — submitter and approver must differ.
Reject a scenario
POST /org/:orgId/scenarios/:id/rejectMoves the scenario to REJECTED. The owner can revise and re-submit.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | Yes | Why the scenario was rejected. Surfaced to the owner in their inbox. |
Merge a scenario
POST /org/:orgId/scenarios/:id/mergeApplies every overlay in the scenario to live data, transactionally. The scenario must be in ACTIVE status.
Response
json
{
"data": {
"success": true,
"mergeLogId": "clx_merge_log_id",
"errors": []
}
}If success is false, errors contains the reasons. The scenario is left untouched on failure.
WARNING
Merge is destructive. There is no automatic unmerge. To undo, create a new scenario with the inverse changes — the merge log gives you the diff you need.
Revert a scenario
POST /org/:orgId/scenarios/:id/revertDrops every overlay on the scenario, returning it to a clean fork of its base. The scenario itself remains; only the changes inside it are discarded.
Remove a single change
POST /org/:orgId/scenarios/:id/changes/removeRemoves a single overlay row from the scenario without touching the rest. Useful for selectively rolling back.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
entityType | string | Yes | One of employee, contractor, vacancy, team, project, aiAgent, allocation. |
changeId | string | Yes | The ID of the overlay row to remove. |
Archive
POST /org/:orgId/scenarios/:id/archiveMoves the scenario to ARCHIVED. Read-only from this point. Merged scenarios are archived automatically.
Delete
DELETE /org/:orgId/scenarios/:idHard-deletes a scenario and every overlay it contains. Returns 204 No Content. Cannot be undone — prefer archive for anything you might need to read again.
Querying live data with a scenario context
Every other endpoint in the API accepts a scenarioId query parameter. Pass a scenario's ID and the endpoint returns the merged view — live data with that scenario's overlays applied.
bash
curl -X GET "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/employees?scenarioId=clx_scenario_id" \
-H "Authorization: Bearer private_..."This is read-only. To mutate inside a scenario, use the corresponding write endpoint with scenarioId set — for example, POST /employees?scenarioId=... creates the employee inside the scenario rather than as live data.
Where to go next
- Scenarios workflow — the conceptual lifecycle.
- Comparing scenarios — diffing two plans.
- Inbox and change review — the approval queue.
- Live data vs scenarios — the data model behind plan overlays.