JSON + Code Native Workflow Orchestration
Applies to both editions
This page describes the Conductor engine that powers both open-source Conductor and Orkes Conductor. Operational defaults mentioned here, such as Redis or Elasticsearch, are specifics of the open-source distribution; Orkes Conductor deployments run the Orkes platform stack.
What "JSON + code native" means mechanically
You can write a workflow definition in JSON directly, or in code using an SDK. Both produce the same thing: a JSON document. When you define a workflow in code, the SDK converts it to that JSON and registers it with the server. The server only ever stores, versions, and executes the JSON. Everything below applies no matter which way the workflow was written.
- Storage. The workflow definition is a JSON document persisted in the data store. The execution engine reads this document to schedule tasks.
- Versioning. Each version is a distinct JSON document. Multiple versions can run concurrently. Running executions use a snapshot taken at start time and are immutable against later changes.
- API parity. The JSON you write in a file is the same JSON you send to the API, see in the UI, and get back from the SDK. There is no compiled intermediate form.
- Dynamic creation. You can construct a workflow definition as a JSON object at runtime and pass it directly to the
StartWorkflowRequestAPI. Conductor executes it immediately without pre-registration.
Dynamic workflows in detail
Conductor supports three levels of runtime flexibility.
1. Dynamic workflow definitions
Pass the complete workflow definition in the StartWorkflowRequest:
{
"name": "dynamic_agent_plan",
"workflowDef": {
"name": "dynamic_agent_plan",
"tasks": [
{
"name": "search_web",
"taskReferenceName": "search",
"type": "HTTP",
"inputParameters": {
"http_request": {
"uri": "https://api.search.com/query",
"method": "POST",
"body": { "q": "${workflow.input.query}" }
}
}
},
{
"name": "summarize",
"taskReferenceName": "summarize",
"type": "SIMPLE"
}
]
},
"input": {
"query": "conductor workflow engine"
}
}
No pre-registration needed. The definition is embedded in the execution and persisted.
2. Dynamic tasks
The DYNAMIC task type resolves which task to execute at runtime:
{
"name": "run_tool",
"taskReferenceName": "tool_call",
"type": "DYNAMIC",
"inputParameters": {
"taskToExecute": "${plan.output.nextTool}"
},
"dynamicTaskNameParam": "taskToExecute"
}
The value of taskToExecute comes from the output of a previous task, such as an LLM choosing a tool. Conductor resolves and schedules that task at runtime.
3. Dynamic fork/join
The FORK_JOIN_DYNAMIC operator creates parallel branches at runtime:
{
"name": "parallel_tool_calls",
"taskReferenceName": "fork",
"type": "FORK_JOIN_DYNAMIC",
"inputParameters": {
"dynamicTasks": "${plan.output.parallelTasks}",
"dynamicTasksInput": "${plan.output.taskInputs}"
},
"dynamicForkTasksParam": "dynamicTasks",
"dynamicForkTasksInputParamName": "dynamicTasksInput"
}
The number of branches, their task types, and their inputs are all decided at runtime. Follow the fork with a JOIN. If an agent produced the branch list, validate it and enforce a branch limit before executing the plan.
A sub-workflow can be selected and parameterized at runtime in the same way. For a governed implementation of runtime-generated plans, with capability allowlists, bounded fan-out, and approval, see Durable Adaptive Graphs.
Deterministic by construction
A JSON definition describes what runs and in what order. It contains no executable code, so it cannot open a database connection, write a file, or call an API on its own. Every side effect happens inside a worker or system task, where it is isolated, testable, and independently deployable. The definition itself is inert data.
Because the definition is inert, execution is deterministic. Given the same inputs, Conductor schedules the same tasks in the same order every time. There is no ambient state and no hidden mutation. That is why replay works unconditionally: restart a workflow from months ago and it re-executes the same graph. Engines that embed orchestration in application code can only promise this by restricting what your code is allowed to do.
The same split keeps orchestration and implementation separate. Sequencing, branching, retries, and timeouts live in the definition. Implementation logic lives in workers, in any language. You can change a worker without touching the workflow, and change the workflow without redeploying workers.
Why this matters for agents
Agents produce structured output, and JSON is native
LLMs already produce structured output in the form of function calls and JSON responses. A Conductor workflow definition is the same kind of object. An LLM can therefore generate a workflow definition directly. Your application validates the plan and applies its policy boundaries, and Conductor executes it.
Runtime generation without compile/deploy
Most engines require code changes, a compile, and a deploy before a new workflow can run. Conductor does not. A planner agent generates a definition as JSON, your code sends it to POST /api/workflow with the definition inline, and Conductor validates, persists, and executes it immediately. The result is as durable, observable, and retryable as any pre-registered workflow.
Inspectability and auditability
Every execution records the definition snapshot it used, every task's input, output, status, and retry history, and the workflow's own input, output, and state transitions. You can query, diff, export, and replay any execution. For agent workflows, that record shows what the agent planned, which tools it called, what the model returned, and what a person approved.
Diffable versioning
Because definitions are JSON, they belong in source control. You can review changes in pull requests, diff two versions to see exactly what changed, and roll back by re-registering an earlier version. Multiple versions can run side by side, which makes canary rollouts straightforward. Running executions are never affected by any of this, because each keeps the snapshot taken at start.
Exposing workflows as APIs and MCP tools
Any Conductor workflow is already an API endpoint:
# Start a workflow (async, returns execution ID)
conductor workflow start -w my_agent -i '{"query": "summarize this document"}'
# Get the result
conductor workflow status {executionId}
Using cURL
A workflow returns the structured output declared by its outputParameters, so services and agents can call it like any other API. A workflow can also be registered as an MCP tool, which lets LLMs and agent frameworks discover and invoke it with structured input and output.
Next steps
- Durable Execution Semantics — What persists, what gets retried, failure matrix.
- Agents & AI — What agents are and how they run on Conductor.
- Run a Workflow from JSON — Register and run a JSON workflow with the CLI.
- Workflow Definition Reference — Full JSON schema for workflow definitions.
- Dynamic Fork — Runtime-determined parallel execution.