# Minimal — Opus adds the input and output nodes for you
curl --request POST \
--url https://operator.opus.com/api/v1/workflow \
--header 'x-service-key: {YOUR_SERVICE_KEY}' \
--header 'x-workspace-id: {YOUR_WORKSPACE_ID}' \
--header 'Content-Type: application/json' \
--data '{
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports"
}'
import requests
response = requests.post(
"https://operator.opus.com/api/v1/workflow",
headers={
"x-service-key": "{YOUR_SERVICE_KEY}",
"x-workspace-id": "{YOUR_WORKSPACE_ID}",
},
json={
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports",
"activeStatus": "inactive",
},
)
print(response.json())
const response = await fetch("https://operator.opus.com/api/v1/workflow", {
method: "POST",
headers: {
"x-service-key": "{YOUR_SERVICE_KEY}",
"x-workspace-id": "{YOUR_WORKSPACE_ID}",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Quarterly Report Processor",
description: "Summarizes quarterly financial reports",
}),
});
const data = await response.json();
console.log(data);
{
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports",
"activeStatus": "inactive",
"nodes": {
"{INPUT_NODE_ID}": {
"id": "{INPUT_NODE_ID}",
"name": "Workflow Input",
"type": "input"
},
"{OUTPUT_NODE_ID}": {
"id": "{OUTPUT_NODE_ID}",
"name": "Workflow Output",
"type": "output"
}
},
"edges": {
"{EDGE_ID}": {
"id": "{EDGE_ID}",
"from_node_id": "{INPUT_NODE_ID}",
"to_node_id": "{OUTPUT_NODE_ID}"
}
}
}
{
"entityId": "{ENTITY_ID}",
"workflowId": "{WORKFLOW_ID}",
"workflowVersionId": "{WORKFLOW_VERSION_ID}",
"builderType": "OPUS_V2"
}
Workflows
Create a Workflow
Create a workflow in a workspace, optionally pre-populated with nodes and edges
POST
/
api
/
v1
/
workflow
# Minimal — Opus adds the input and output nodes for you
curl --request POST \
--url https://operator.opus.com/api/v1/workflow \
--header 'x-service-key: {YOUR_SERVICE_KEY}' \
--header 'x-workspace-id: {YOUR_WORKSPACE_ID}' \
--header 'Content-Type: application/json' \
--data '{
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports"
}'
import requests
response = requests.post(
"https://operator.opus.com/api/v1/workflow",
headers={
"x-service-key": "{YOUR_SERVICE_KEY}",
"x-workspace-id": "{YOUR_WORKSPACE_ID}",
},
json={
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports",
"activeStatus": "inactive",
},
)
print(response.json())
const response = await fetch("https://operator.opus.com/api/v1/workflow", {
method: "POST",
headers: {
"x-service-key": "{YOUR_SERVICE_KEY}",
"x-workspace-id": "{YOUR_WORKSPACE_ID}",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Quarterly Report Processor",
description: "Summarizes quarterly financial reports",
}),
});
const data = await response.json();
console.log(data);
{
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports",
"activeStatus": "inactive",
"nodes": {
"{INPUT_NODE_ID}": {
"id": "{INPUT_NODE_ID}",
"name": "Workflow Input",
"type": "input"
},
"{OUTPUT_NODE_ID}": {
"id": "{OUTPUT_NODE_ID}",
"name": "Workflow Output",
"type": "output"
}
},
"edges": {
"{EDGE_ID}": {
"id": "{EDGE_ID}",
"from_node_id": "{INPUT_NODE_ID}",
"to_node_id": "{OUTPUT_NODE_ID}"
}
}
}
{
"entityId": "{ENTITY_ID}",
"workflowId": "{WORKFLOW_ID}",
"workflowVersionId": "{WORKFLOW_VERSION_ID}",
"builderType": "OPUS_V2"
}
Create a workflow in the workspace named by the
The matching edges then carry the route:
x-workspace-id header.
nodes and edges are optional — omit them and Opus creates the workflow with an input node and an output node already wired, ready to open in the Builder. Supply them to stand up a complete graph in a single call.
Requires the Workflow: Full permission in the target workspace.
Prefer to describe the workflow in plain language instead of building the graph yourself? Use Generate Workflow and let Opus AI agents design it for you.
Headers
string
required
Your API authentication key
string
required
UUID of the workspace to create the workflow in
Body Parameters
string
required
Workflow name
string
Workflow description
object
Workflow nodes keyed by node ID. Each map key must equal the
id of the node it holds.A node’s handler_class determines the shape of its process — see Node Process Types.Show Node object
Show Node object
string
required
Node ID (UUID). Must match the key this node is stored under.
string
required
Node name
string
required
Node type — for example
input, output, agent, integration, codestring
Node description
string
Handler ID
string
Handler version ID
string
Active handler ID
string
Active handler version ID
string
Which variety of this node type — it determines the shape of
process. See Node Process Types.object
Input variable schema — see Variable Schemas
object
Output variable schema — see Variable Schemas
object
Variable mappings — which upstream variable feeds each input. See Connecting Variables Between Nodes.
object
The step’s configuration. Its shape is determined by
handler_class — see Node Process Types.object
object
Fixed input/output values — see Fixed Values
object
object
Public execution settings
object
Workflow edges keyed by edge ID. Each map key must equal the
id of the edge it holds, and from_node_id and to_node_id must name nodes present in nodes.Show Edge object
Show Edge object
string
default:"inactive"
Workflow active status. One of
active or inactive.string[]
Org units to tag the new workflow to at creation. Maximum 100.Tagging is best-effort: if a tag can’t be applied, the workflow is still created and the call still succeeds.
Node and edge objects use snake_case keys (
from_node_id, input_schema), while the top-level body fields use camelCase (activeStatus, orgUnitIds). This is deliberate — nodes and edges are forwarded to the workflow executor verbatim.Routing
A route is a conditional branch out of a node. Wiring one up touches four places, and all four must agree or the route is orphaned:1
Declare the route
Add an entry to the node’s
routes, keyed by the route ID.2
Back it with a boolean output variable
Add a
bool variable to the node’s output_schema whose schema key is the route ID. This variable is what the node sets at runtime to decide whether the branch is taken.3
Mark the node
Include
route in the node’s properties.4
Point the edges at it
Set
route_id on each edge that belongs to the route. Use route_complement on the edge that should be taken when the route’s boolean is false.routing
{
"routes": {
"{ROUTE_ID}": {
"id": "{ROUTE_ID}",
"name": "Needs Approval",
"description": "Taken when the amount exceeds the auto-approval limit"
}
},
"properties": ["route"],
"output_schema": {
"schema": {
"{ROUTE_ID}": {
"id": "{ROUTE_ID}",
"variable_name": "needs_approval",
"allowed_types": [{ "type": "bool" }]
}
},
"variable_addition_allowed": true
}
}
edges
"edges": {
"{EDGE_A}": {
"id": "{EDGE_A}",
"from_node_id": "{NODE_ID}",
"to_node_id": "{APPROVAL_NODE_ID}",
"route_id": "{ROUTE_ID}"
},
"{EDGE_B}": {
"id": "{EDGE_B}",
"from_node_id": "{NODE_ID}",
"to_node_id": "{SKIP_NODE_ID}",
"route_id": "{ROUTE_ID}",
"route_complement": true
}
}
Response
string
required
The workflow ID. Use this as
{workflowId} in Get Workflow Details, Update a Workflow, and Get Run Status.string
required
The ID of the workflow’s entry in the Opus catalog. Most integrations only need
workflowId.string
required
The ID of the first workflow version
string
required
Builder type. One of
OPUS_V1 or OPUS_V2.Errors
Bad Request
Missing or malformed
x-workspace-id header.Unauthorized
Missing, invalid, or expired API key.
Forbidden
No access to that workspace.
Not Found
The workspace or user does not exist.
# Minimal — Opus adds the input and output nodes for you
curl --request POST \
--url https://operator.opus.com/api/v1/workflow \
--header 'x-service-key: {YOUR_SERVICE_KEY}' \
--header 'x-workspace-id: {YOUR_WORKSPACE_ID}' \
--header 'Content-Type: application/json' \
--data '{
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports"
}'
import requests
response = requests.post(
"https://operator.opus.com/api/v1/workflow",
headers={
"x-service-key": "{YOUR_SERVICE_KEY}",
"x-workspace-id": "{YOUR_WORKSPACE_ID}",
},
json={
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports",
"activeStatus": "inactive",
},
)
print(response.json())
const response = await fetch("https://operator.opus.com/api/v1/workflow", {
method: "POST",
headers: {
"x-service-key": "{YOUR_SERVICE_KEY}",
"x-workspace-id": "{YOUR_WORKSPACE_ID}",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Quarterly Report Processor",
description: "Summarizes quarterly financial reports",
}),
});
const data = await response.json();
console.log(data);
{
"name": "Quarterly Report Processor",
"description": "Summarizes quarterly financial reports",
"activeStatus": "inactive",
"nodes": {
"{INPUT_NODE_ID}": {
"id": "{INPUT_NODE_ID}",
"name": "Workflow Input",
"type": "input"
},
"{OUTPUT_NODE_ID}": {
"id": "{OUTPUT_NODE_ID}",
"name": "Workflow Output",
"type": "output"
}
},
"edges": {
"{EDGE_ID}": {
"id": "{EDGE_ID}",
"from_node_id": "{INPUT_NODE_ID}",
"to_node_id": "{OUTPUT_NODE_ID}"
}
}
}
{
"entityId": "{ENTITY_ID}",
"workflowId": "{WORKFLOW_ID}",
"workflowVersionId": "{WORKFLOW_VERSION_ID}",
"builderType": "OPUS_V2"
}
Was this page helpful?