Creating Workflow Orders with the Cellario OS REST API
A developer guide for integrating with Cellario OS to discover workflow definitions and submit workflow orders over HTTP.
Table of Contents
1. Introduction & Concepts
1.1 Purpose & audience
This guide is for developers on your team who need to create Cellario OS workflow orders programmatically over a REST API. By the end you will be able to:
- Discover which workflow definitions are available and which version to target.
- Read a workflow definition's parameters (their IDs and types).
- Build and submit a workflow order with concrete argument values.
- Read back the created order's system ID, human-facing ID, and state.
1.2 The big picture
Creating a workflow order is a short, linear flow:
┌──────────────────────┐ ┌──────────────────────────┐ ┌─────────────────────┐
│ 1. Discover workflow │ --> │ 2. Read its parameters │ --> │ 3. Build arguments │
│ (list published) │ │ (get definition) │ │ (parameter_id + │
│ → workflow_id + │ │ → parameter_id, name, │ │ value) │
│ version │ │ type per parameter │ │ │
└──────────────────────┘ └──────────────────────────┘ └─────────┬───────────┘
│
┌─────────────────▼───────────────┐
│ 4. POST the Workflow Order │
│ → id, user_facing_id, state │
└───────────────────────────────────┘1.3 Core definitions
Term | Definition |
|---|---|
Workflow definition | A versioned, published template describing a lab process — its steps, connections, and parameters. Identified by a workflow_id (UUID) plus a workflow_version (a semantic version string such as 1.2.0). A given version is immutable; publishing changes produces a new version. |
Workflow order | A single request to execute one workflow definition version, supplying concrete arguments. When created it receives a system id (UUID), a human-friendly user_facing_id (for example SCI-10), and a state. |
Parameter | A named, typed input declared by a workflow definition. Each parameter carries a parameter_id and a parameter_type_descriptor that holds its name, type, required flag, and default_value. |
Argument | The value you supply for a parameter when creating an order. An argument references the parameter by its workflow_parameter_id (which equals the definition's parameter_id) and carries a value. |
Metadata | Ownership and timestamp fields carried on the order (created_by_user_id, created_at, and so on). |
Publication status & versioning. Only published workflow definitions can be ordered. Each definition can have several versions; the discovery endpoint returns the latest published version of each. Versions are semantic version strings (1.2.0, 1.17.0).
Order lifecycle / states. Once created, a workflow order moves through states that are set and advanced by Cellario OS — observed values include PENDING and IN_PROGRESS. Your integration submits the order; Cellario OS owns the transitions after that.
1.4 Parameter types
A parameter's type is described by two fields inside its parameter_type_descriptor, both written in SCREAMING_SNAKE_CASE:
- type — the base value type (TaskParameterType).
- validation.format — an optional format that refines a STRING into a more specific type (ParameterDescriptorFormat).
Together they produce the parameter types you see in the Cellario OS UI. The table below lists every combination.
Effective parameter types
UI type | type | validation.format | JSON value you send |
|---|---|---|---|
Text | STRING | NONE | A JSON string, e.g. "Main Lab" |
Integer | INT | — | A JSON number, e.g. 3 |
Float | FLOAT | — | A JSON number, e.g. 1.5 |
Boolean | BOOLEAN | — | A JSON boolean, e.g. true |
Date | STRING | DATE | A JSON string date, e.g. "2026-07-09" |
Time | STRING | TIME | A JSON string time, e.g. "13:45:00" |
Date / Time | STRING | DATE_TIME | A JSON string ISO-8601 datetime, e.g. "2026-07-09T13:45:00Z" |
File link (URL) | STRING | URL | A JSON string URL, e.g. "https://example.com/doc.pdf" |
File | STRING | FILE | Not sent in arguments — uploaded separately. See §4.7. |
The base type values (TaskParameterType) are: STRING, INT, FLOAT, BOOLEAN, ARRAY, OBJECT, DICTIONARY. The validation.format values (ParameterDescriptorFormat) are: NONE, DATE, TIME, DATE_TIME, FILE, URL. ARRAY/OBJECT/DICTIONARY are advanced/structured types — send ARRAY as a JSON array and OBJECT/DICTIONARY as a JSON object.
The value matches the parameter's type
Send each argument's value as the native JSON type for the parameter (see the table above):
- STRING (and its DATE/TIME/DATE_TIME/URL formats) → JSON string
- INT, FLOAT → JSON number
- BOOLEAN → JSON boolean (true / false)
- ARRAY → JSON array; OBJECT/DICTIONARY → JSON object
- FILE → not sent here; uploaded to the order (§4.7)
For example, a live order argument for a BOOLEAN parameter and an INT parameter looks like this — note the values are not quoted strings:
[
{ "workflow_parameter_id": "7be450cd-df0f-49d5-8060-3c3121a5757d", "value": true },
{ "workflow_parameter_id": "28e4ed10-02b2-4667-a4bc-849d19ca303f", "value": 3 }
]2. Getting Started / Prerequisites
2.1 Base URL / environments
All endpoints are served by the Cellario OS Data Access API, which is mounted under the /api/data-access path of your environment host. Throughout this guide the combined host + prefix is written as {BASE_URL}:
{BASE_URL} = https://<host>/api/data-accessSo the three endpoints resolve to:
{BASE_URL}/v2/workflows/latest-published
{BASE_URL}/v2/workflows/id/{id}/version/{version}
{BASE_URL}/v1/workflow-ordersHighRes will tell you the exact host to use for your environment.
2.2 Authentication
Every request is authenticated with a single API key sent in the x-api-key header. This applies to both the read/discovery endpoints and the order-creation endpoint.
x-api-key: <your-api-key>HighRes will provide you with an API key. Send it in the x-api-key header on every call.
2.3 Conventions
- Format: All request and response bodies are JSON (Content-Type: application/json).
- Field naming: Fields use snake_case (for example workflow_id, workflow_parameter_id).
- Identifiers: IDs are UUIDs (for example 5bf15954-5c51-4832-900f-269a8edbbcdd).
- Timestamps: ISO-8601 in UTC (for example 2026-07-07T19:44:40.015546Z)
- API versions: Discovery uses the /v2 API; workflow orders use the /v1 API. (There is no /v2/workflow-orders — see §4.1.)
3. Querying for Workflow Definitions & Parameters
Before you can create an order you need two things: the workflow ID + version of the process you want to run, and the parameter IDs for the inputs you want to supply. This section covers both.
3.1 List available workflows
Returns the latest published version of every workflow definition. Use this to find the workflow you want and capture its id and version.
Request
GET {BASE_URL}/v2/workflows/latest-published
x-api-key: <your-api-key>Response — an array of workflow summaries:
[
{
"id": "5b41b61d-04ce-431d-ac8e-831d4eda5b6f",
"name": "TestLoopsAndDecisions",
"description": "",
"version": "1.17.0",
"status": "Published",
"step_count": 6,
"last_modified": "2026-07-07T19:44:40.015546Z",
"last_modified_by": "96258bfc-3e4e-48e4-89e6-523a67bb86f1"
}
]Response fields
Field | Type | Description |
|---|---|---|
id | UUID | The workflow definition ID. You will send this as workflow_id. |
name | string | Human-readable workflow name |
description | string | Optional description |
version | string | The latest published version (send as workflow_version) |
status | string | Publication status (e.g. Published) |
step_count | number | Number of steps in the workflow |
last_modified | datetime | When this version was last modified |
last_modified_by | UUID | User who last modified it |
Pick the workflow you want by name, then capture its id and version for the next call.
3.2 Retrieve a single workflow definition
Returns the full definition for one specific workflow version, including the parameters you will supply values for.
Request
GET {BASE_URL}/v2/workflows/id/{id}/version/{version}
x-api-key: <your-api-key>Example: GET {BASE_URL}/v2/workflows/id/5b41b61d-04ce-431d-ac8e-831d4eda5b6f/version/1.17.0
Response (abridged — one parameter shown in full)
{
"id": "5b41b61d-04ce-431d-ac8e-831d4eda5b6f",
"name": "TestLoopsAndDecisions",
"description": "",
"metadata": {
"version": "1.17.0",
"created": "2026-07-07T19:44:40.015546Z",
"created_by": "96258bfc-3e4e-48e4-89e6-523a67bb86f1",
"updated": "2026-07-07T19:44:40.015546Z",
"updated_by": "96258bfc-3e4e-48e4-89e6-523a67bb86f1"
},
"parameters": [
{
"id": "e6338599-8174-4631-b383-946c8deee693",
"parameter_id": "adb329b3-346d-40b5-a03d-357798342f14",
"parameter_type_descriptor": {
"id": "18d2e97d-27d3-4b23-9861-9910868568a3",
"name": "loopControl",
"type": "BOOLEAN",
"read_only": false,
"required": false,
"default_value": "true",
"validation": { "format": "NONE" },
"display_hints": { "description": "" }
},
"description": "",
"index": 0
}
],
"steps": [ /* ... workflow steps (not needed to create an order) ... */ ],
"connections": [ /* ... connections between steps ... */ ]
}The parameters[] array — the important part
Each entry describes one input the workflow accepts. Note the two IDs and the nested descriptor:
Field | Type | Description |
|---|---|---|
id | UUID | The parameter's row ID within this workflow version. Not what you send in an order. |
parameter_id | UUID | The ID you send as workflow_parameter_id in an order argument |
parameter_type_descriptor | object | Describes the parameter (see below). |
description | string | Optional description |
index | number | Ordering index within the workflow |
parameter_type_descriptor (the fields you care about):
Field | Type | Description |
|---|---|---|
name | string | The parameter's name (for example loopControl). Use this to know which parameter you are setting. |
type | string | The parameter type — STRING, BOOLEAN, INT, ARRAY, … (see §1.4) |
required | boolean | Whether an argument for this parameter is mandatory |
default_value | string | Value used if you omit the argument |
validation | object | Validation rules, e.g. { "format": "NONE" } |
Mapping name → ID. You will generally know parameters by their name (loopControl, LoopCount, …). To build an order you translate each name into its parameter_id (from the same parameter entry) and send that as the workflow_parameter_id. For example, loopControl → adb329b3-346d-40b5-a03d-357798342f14.
3.3 Errors & edge cases
Situation | What to expect / do |
|---|---|
Unknown workflow id or version | The definition endpoint returns an error (e.g. 404 Not Found). Re-list published workflows to confirm the current id/version. |
Workflow not published | It will not appear in latest-published. Only published versions can be ordered. |
Empty parameters array | The workflow accepts no inputs; submit the order with an empty arguments list. |
Missing/invalid API key | 401 / 403. Confirm the x-api-key header is present and correct. |
4. Creating a Workflow Order
4.1 Endpoint
POST {BASE_URL}/v1/workflow-orders
x-api-key: <your-api-key>
Content-Type: application/json4.2 Request body
{
"workflow_id": "5b41b61d-04ce-431d-ac8e-831d4eda5b6f",
"workflow_version": "1.17.0",
"name": "TestLoopsAndDecisions - demo order",
"description": "Created via the REST API",
"arguments": [
{ "workflow_parameter_id": "adb329b3-346d-40b5-a03d-357798342f14", "value": true },
{ "workflow_parameter_id": "6f0a1e2b-...-...", "value": 3 },
{ "workflow_parameter_id": "9c2d3e4f-...-...", "value": "Main Lab" }
],
"metadata": {
"created_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-07-08T18:23:13.444Z",
"last_updated_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"last_update": "2026-07-08T18:23:13.444Z",
"assigned_to_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tags": ["demo"]
}
}Top-level fields
Field | Type | Required | Description |
|---|---|---|---|
workflow_id | UUID | yes | The workflow definition ID from §3.1 |
workflow_version | string | yes | The version to run from §3.1 |
name | string | yes | A name for this order |
description | string | no | Free-text description |
arguments | array | yes | One entry per parameter you are supplying (see below). May be empty if the workflow has no parameters. |
metadata | object | yes | Ownership and timestamps (see below) |
arguments[]
metadata
Field | Type | Description |
|---|---|---|
created_by_user_id | UUID | User creating the order |
created_at | datetime | Creation timestamp (ISO-8601 UTC) |
last_updated_by_user_id | UUID | User for the last update (same as creator on create) |
last_update | datetime | Last-update timestamp |
assigned_to_user_id | UUID | User the order is assigned to |
tags | string[] | Optional free-form tags |
4.3 Response
On success the API returns the created order, adding id, user_facing_id, and state (and echoing arguments, plus a resolved parameters array):
{
"id": "745b6672-0b94-442e-b565-e119a4d463bf",
"workflow_id": "5b41b61d-04ce-431d-ac8e-831d4eda5b6f",
"workflow_version": "1.17.0",
"name": "TestLoopsAndDecisions - demo order",
"description": "Created via the REST API",
"arguments": [
{ "workflow_parameter_id": "adb329b3-346d-40b5-a03d-357798342f14", "value": true }
],
"parameters": [ /* resolved parameter details for this order */ ],
"metadata": {
"created_by_user_id": "16b13604-2760-48fc-accd-8935d5554bce",
"created_at": "2026-07-08T17:47:17.171636Z",
"last_updated_by_user_id": "16b13604-2760-48fc-accd-8935d5554bce",
"last_update": "2026-07-08T17:47:17.171636Z"
},
"user_facing_id": "SCI-1855",
"state": "PENDING"
}Additional response fields
Field | Type | Description |
|---|---|---|
id | UUID | The system ID of the created order. Use it for follow-up operations. |
user_facing_id | string | Human-friendly identifier shown in Cellario OS (e.g. SCI-1855) |
state | string | The order's current state (e.g. PENDING) |
4.4 Worked end-to-end example
- Discover — GET /v2/workflows/latest-published; find "TestLoopsAndDecisions", capture id = 5b41b61d-… and version = 1.17.0.
- Read parameters — GET /v2/workflows/id/5b41b61d-…/version/1.17.0; for each parameter note parameter_type_descriptor.name, .type, and the sibling parameter_id.
- Build arguments — map each name to its parameter_id; set each value as the native JSON type for that parameter's type.
- Submit — POST /v1/workflow-orders with the body from §4.2.
- Read result — capture id, user_facing_id, and state from the response.
The Python example performs exactly these steps.
4.5 Validation & error handling
Problem | Likely status | Fix |
|---|---|---|
Missing a required parameter's argument | 400 Bad Request | Include an argument for every required parameter. |
workflow_id/workflow_version not found | 404 Not Found | Re-list published workflows; use a current id/version. |
Wrong value type for a parameter | 400 Bad Request | Match the JSON type to the parameter's type (string/boolean/number/array). |
Using /v2/workflow-orders | 404 Not Found | Orders are on /v1. |
Missing/invalid API key | 401 / 403 | Confirm the x-api-key header. |
4.6 (Optional) Related operations
For lifecycle completeness — not required to create an order:
Operation | Verb & path |
|---|---|
List workflow orders | GET {BASE_URL}/v1/workflow-orders |
Get one order | GET {BASE_URL}/v1/workflow-orders/{id} |
Update an order | PUT {BASE_URL}/v1/workflow-orders/{id} |
4.7 File parameters: uploading files to an order
Some workflows declare file parameters. A file is not passed as an argument value — you supply it by uploading the file to the order after it is created and before it is started. The value in arguments is skipped for file parameters; the upload associates the file with the parameter instead.
Procedure
- Create the workflow order (§4.2) and note the returned order id. Include arguments for the non-file parameters as usual; omit the file parameters from arguments.
- Identify the file parameters from the workflow definition (§3.2) — every parameter whose parameter_type_descriptor.type is STRING and whose parameter_type_descriptor.validation.format is FILE. Note each one's parameter_id.
- Upload one file per file parameter to the endpoint below, once for each file parameter, using that parameter's parameter_id.
- Start the order (§4.8). Only after every file parameter has its file uploaded.
Upload endpoint
POST {BASE_URL}/v1/workflow-orders/{orderId}/files?parameter_id={parameterId}
x-api-key: <your-api-key>
Content-Type: multipart/form-dataPart | Description |
|---|---|
Path orderId | The id of the order created in step 1 |
Query parameter_id | The parameter_id of the file parameter this file is for |
Body | The file, sent as multipart/form-data |
Call this endpoint once per file parameter. If a workflow has three file parameters, you make three uploads against the same orderId, each with a different parameter_id.
Full flow
1. POST /v1/workflow-orders -> order id (state: PENDING)
2. (read definition; collect FILE parameter_ids)
3. POST /v1/workflow-orders/{id}/files?parameter_id=A -> upload file A
POST /v1/workflow-orders/{id}/files?parameter_id=B -> upload file B
4. POST /v1/workflow-orders/{id}/request-start (only now — see §4.8)Notes & error handling
Situation | Guidance |
|---|---|
Uploading after the order has started | Not allowed — upload before starting. |
Missing a file for a required file parameter | The order may fail to start / run. Upload a file for every required file parameter. |
Unknown orderId or parameter_id | 404 Not Found — confirm both IDs. |
Multipart form field name | Send the file as a standard multipart/form-data file part. Confirm the expected field name against your environment's OpenAPI/Swagger if an upload is rejected. |
4.8 Starting an order
Creating an order (and uploading any files) does not run it. A newly created order sits in the PENDING state until you explicitly request it to start.
Endpoint
POST {BASE_URL}/v1/workflow-orders/{orderId}/request-start
x-api-key: <your-api-key>- Path orderId — the id returned when you created the order
- No request body
- For orders with file parameters, upload all files first (§4.7); starting an order is the point of no return for populating file parameters.
Response — a WorkflowOrderStateResponse describing the state transition:
{
"order_id": "745b6672-0b94-442e-b565-e119a4d463bf",
"previous_state": "PENDING",
"state": "STARTING"
}Field | Type | Description |
|---|---|---|
order_id | UUID | The order that was started |
previous_state | string | The state before this request (e.g. PENDING) |
state | string | The state after this request (e.g. STARTING) |
Order states. The state values are:
State | Meaning |
|---|---|
PENDING | Created, not yet started |
STARTING | Start has been requested; the order is being brought up. |
IN_PROGRESS | Running |
COMPLETED | Finished successfully |
CANCELLING | A cancel has been requested. |
CANCELLED | Cancelled |
After request-start, an order typically moves PENDING → STARTING → IN_PROGRESS; the later transitions are driven by Cellario OS, not by your call.
Errors
Situation | Guidance |
|---|---|
Unknown orderId | 404 Not Found — confirm the order id. |
Order not in a startable state (e.g. already running) | The request is rejected — only PENDING orders can be started. |
Missing/invalid API key | 401 / 403 |
4.9 Canceling an order
Request that an order be canceled. This works on an order that is pending or running; Cellario OS drives the actual wind-down (CANCELLING → CANCELLED).
Endpoint
POST {BASE_URL}/v1/workflow-orders/{orderId}/request-cancel
x-api-key: <your-api-key>
Content-Type: application/json- Path orderId — the id of the order to cancel
- Request body — a CancelWorkflowOrderRequest. The one field is optional:
{
"cancellation_reason": "Submitted in error"
}Field | Type | Required | Description |
|---|---|---|---|
cancellation_reason | string | no | Free-text reason recorded with the cancellation |
You may send an empty body ({}) or omit cancellation_reason entirely.
Response — 200 OK with no body on success
Order states. A cancel request typically moves an order … → CANCELLING → CANCELLED; the transitions are driven by Cellario OS. See the state table in §4.8.
Errors
Situation | Guidance |
|---|---|
Unknown orderId | 404 Not Found — confirm the order id. |
Order not in a cancellable state (e.g. already completed/canceled) | The request is rejected. |
Missing/invalid API key | 401 / 403 |
5. Reference Appendix
5.1 Endpoint quick reference
Verb | Path (under {BASE_URL} = https://<host>/api/data-access) | Auth | Purpose |
|---|---|---|---|
GET | /v2/workflows/latest-published | x-api-key | List latest published workflows. |
GET | /v2/workflows/id/{id}/version/{version} | x-api-key | Get one workflow definition (with parameters). |
POST | /v1/workflow-orders | x-api-key | Create a workflow order. |
GET | /v1/workflow-orders | x-api-key | List workflow orders. |
POST | /v1/workflow-orders/{orderId}/files?parameter_id={parameterId} | x-api-key | Upload a file for a file parameter (before starting the order). See §4.7. |
POST | /v1/workflow-orders/{orderId}/request-start | x-api-key | Start a created order. See §4.8. |
POST | /v1/workflow-orders/{orderId}/request-cancel | x-api-key | Cancel a pending/running order. See §4.9. |
5.2 Object schemas
WorkflowSummary (list item)
id: UUID, name: string, description: string, version: string,
status: string, step_count: number, last_modified: datetime, last_modified_by: UUIDWorkflowDefinition
id: UUID, name: string, description: string,
metadata: { version, created, created_by, updated, updated_by },
parameters: Parameter[], steps: [], connections: []Parameter
id: UUID, # row id within this workflow version (not used in orders)
parameter_id: UUID, # <-- send this as workflow_parameter_id
parameter_type_descriptor: {
id: UUID, name: string, type: string, # type: STRING | BOOLEAN | INT | ARRAY | ...
required: boolean, read_only: boolean, default_value: string,
validation: { format: string }, display_hints: { description: string }
},
description: string, index: numberCreateWorkflowOrderRequest
workflow_id: UUID, workflow_version: string, name: string, description: string,
arguments: Argument[], metadata: MetadataArgument
workflow_parameter_id: UUID, # == definition's parameter_id
value: any # native JSON type matching the parameter's typeMetadata
created_by_user_id: UUID, created_at: datetime,
last_updated_by_user_id: UUID, last_update: datetime,
assigned_to_user_id: UUID, tags: string[]WorkflowOrder (create/list response = request + these)
id: UUID, user_facing_id: string, state: string, parameters: []5.3 Parameter type reference
A parameter type is the combination of type (TaskParameterType) and validation.format (ParameterDescriptorFormat). Both serialize in SCREAMING_SNAKE_CASE.
UI type | type | validation.format | JSON value | Example |
|---|---|---|---|---|
Text | STRING | NONE | JSON string | "Main Lab" |
Integer | INT | — | JSON number | 3 |
Float | FLOAT | — | JSON number | 1.5 |
Boolean | BOOLEAN | — | JSON boolean | true |
Date | STRING | DATE | JSON string | "2026-07-09" |
Time | STRING | TIME | JSON string | "13:45:00" |
Date / Time | STRING | DATE_TIME | JSON string | "2026-07-09T13:45:00Z" |
File link (URL) | STRING | URL | JSON string | "https://example.com/doc.pdf" |
File | STRING | FILE | (none in arguments) | Uploaded separately — §4.7 |
Base type values (TaskParameterType): STRING, INT, FLOAT, BOOLEAN, ARRAY, OBJECT, DICTIONARY. Send ARRAY as a JSON array and OBJECT/DICTIONARY as a JSON object.
validation.format values (ParameterDescriptorFormat): NONE, DATE, TIME, DATE_TIME, FILE, URL.
Always confirm a parameter's type and validation.format from its definition. Send value as the native JSON type — do not wrap it in a string.
File parameters are the exception: type = STRING, validation.format = FILE. They are not included in arguments; instead a file is uploaded to the order after creation (see §4.7).
5.4 Full example payloads
See §4.2 (request) and §4.3 (response), and the runnable versions in the Python example.
5.5 Glossary
- Workflow definition — versioned template of a lab process
- Workflow order — one execution request against a definition version
- Parameter — a typed input declared by a definition (parameter_id + parameter_type_descriptor)
- Argument — a value supplied for a parameter in an order
- user_facing_id — the human-readable order identifier (e.g. SCI-1855)
5.6 Runnable Python examples
The Python example is a small, dependency-light client (requests only) that implements discovery and order creation, plus a walkthrough.py script that chains the whole flow.