Skip to main content

Orchestration API

Execute multiple tool calls in a single request with automatic concurrency optimization. Read-only tools run in parallel while mutating tools serialize, reducing total execution time without sacrificing safety.
The orchestration API requires bearer token authentication. All requests are subject to the general API rate limit of 120 requests per minute.

Execute batch

POST /api/orchestration/batch
Submit a batch of tool calls for concurrent execution. The system automatically classifies each tool as read-only or mutating, partitions them into execution batches, and runs them with optimal concurrency. Requires bearer token authentication.

Request body

FieldTypeRequiredDescription
toolsarrayYesArray of tool call objects to execute. Minimum 1, maximum 20.
tools[].idstringYesUnique identifier for this tool call
tools[].toolNamestringYesName of the tool to invoke (for example, read, grep, write, bash)
tools[].inputobjectYesInput parameters for the tool call
userIdstringNoUser identifier. Used for server-side logging and monitoring. Not validated against the authenticated session.
{
  "tools": [
    { "id": "t1", "toolName": "read", "input": { "path": "/src/index.ts" } },
    { "id": "t2", "toolName": "grep", "input": { "pattern": "TODO" } },
    { "id": "t3", "toolName": "write", "input": { "path": "/src/config.ts", "content": "..." } },
    { "id": "t4", "toolName": "read", "input": { "path": "/src/utils.ts" } }
  ]
}
In this example, t1 and t2 are read-only and run in parallel. t3 is mutating and runs alone. t4 is read-only and runs after t3 completes.

Response

{
  "result": {
    "success": true,
    "results": [
      {
        "toolId": "t1",
        "toolName": "read",
        "success": true,
        "output": { "..." : "..." },
        "durationMs": 12
      },
      {
        "toolId": "t2",
        "toolName": "grep",
        "success": true,
        "output": { "..." : "..." },
        "durationMs": 8
      },
      {
        "toolId": "t3",
        "toolName": "write",
        "success": true,
        "output": { "..." : "..." },
        "durationMs": 45
      },
      {
        "toolId": "t4",
        "toolName": "read",
        "success": true,
        "output": { "..." : "..." },
        "durationMs": 10
      }
    ],
    "stats": {
      "totalTools": 4,
      "parallelBatches": 2,
      "serialBatches": 1,
      "maxParallelism": 2,
      "totalDurationMs": 75
    }
  },
  "partition": {
    "batches": 3,
    "totalTools": 4,
    "parallelBatches": 2,
    "serialBatches": 1,
    "maxParallelism": 2,
    "estimatedSpeedup": "133%"
  }
}
FieldTypeDescription
result.successbooleantrue if all tool calls succeeded
result.resultsarrayOrdered list of tool execution results
result.results[].toolIdstringThe id from the original tool call
result.results[].toolNamestringThe tool that was executed
result.results[].successbooleanWhether this tool call succeeded
result.results[].outputanyTool output (shape depends on the tool)
result.results[].errorstringError message if the tool call failed
result.results[].durationMsnumberExecution time in milliseconds
result.stats.totalToolsnumberTotal tool calls in the batch
result.stats.parallelBatchesnumberNumber of batches that ran in parallel
result.stats.serialBatchesnumberNumber of batches that ran serially
result.stats.maxParallelismnumberLargest number of tools in a single parallel batch
result.stats.totalDurationMsnumberWall-clock time for the entire batch
partition.batchesnumberTotal number of execution batches
partition.estimatedSpeedupstringEstimated speedup from parallelization

Errors

CodeDescription
400tools array required — missing or empty tools field
400Maximum 20 tools per batch — batch size exceeds the limit
401Unauthorized — missing or invalid bearer token
500Internal server error
Individual tool call objects are not validated for required fields (id, toolName) at the API level. Malformed tool objects are passed to the executor and may produce runtime errors in the tool results.

Serial failure behavior

When a mutating tool fails during serial execution, the batch stops immediately. Remaining tools in that serial batch are not executed. Parallel batches that already completed are unaffected.

Partition (dry run)

POST /api/orchestration/partition
Preview how tool calls would be partitioned without executing them. Use this to debug batch composition or estimate parallelization gains. Requires bearer token authentication.

Request body

FieldTypeRequiredDescription
toolsarrayYesArray of tool call objects (same format as the batch endpoint)
{
  "tools": [
    { "id": "t1", "toolName": "read", "input": { "path": "/src/a.ts" } },
    { "id": "t2", "toolName": "read", "input": { "path": "/src/b.ts" } },
    { "id": "t3", "toolName": "write", "input": { "path": "/src/c.ts" } },
    { "id": "t4", "toolName": "grep", "input": { "pattern": "error" } }
  ]
}

Response

{
  "batches": [
    {
      "parallel": true,
      "tools": [
        {
          "call": { "id": "t1", "toolName": "read", "input": { "path": "/src/a.ts" } },
          "class": "readonly",
          "reason": "read is read-only"
        },
        {
          "call": { "id": "t2", "toolName": "read", "input": { "path": "/src/b.ts" } },
          "class": "readonly",
          "reason": "read is read-only"
        }
      ]
    },
    {
      "parallel": false,
      "tools": [
        {
          "call": { "id": "t3", "toolName": "write", "input": { "path": "/src/c.ts" } },
          "class": "mutating",
          "reason": "write is mutating"
        }
      ]
    },
    {
      "parallel": true,
      "tools": [
        {
          "call": { "id": "t4", "toolName": "grep", "input": { "pattern": "error" } },
          "class": "readonly",
          "reason": "grep is read-only"
        }
      ]
    }
  ],
  "stats": {
    "totalTools": 4,
    "parallelBatches": 2,
    "serialBatches": 1,
    "maxParallelism": 2,
    "estimatedSpeedup": "133%"
  }
}
FieldTypeDescription
batchesarrayOrdered list of execution batches
batches[].parallelbooleantrue if tools in this batch run concurrently
batches[].toolsarrayClassified tool calls in this batch
batches[].tools[].callobjectOriginal tool call object
batches[].tools[].classstringConcurrency classification: readonly or mutating
batches[].tools[].reasonstringExplanation of the classification
stats.totalToolsnumberTotal tool calls
stats.parallelBatchesnumberNumber of parallel batches
stats.serialBatchesnumberNumber of serial batches
stats.maxParallelismnumberLargest parallel batch size
stats.estimatedSpeedupstringRough speedup estimate

Errors

CodeDescription
400tools array required — missing or non-array tools field
401Unauthorized — missing or invalid bearer token
500Internal server error

Tool classification

Each tool is classified as readonly (parallelizable) or mutating (must serialize). Unknown tools default to mutating as a safety measure.

Read-only tools

These tools have no side effects and can safely run in parallel:
CategoryTool names
File readsread, file_read, file_read_tool
Searchgrep, search, find, glob
System infobash_status, docker_ps, docker_logs, docker_inspect
Webweb_fetch, web_search, http_get
Memorymemory_search, memory_get

Mutating tools

These tools modify state and must run one at a time:
CategoryTool names
File writeswrite, file_write, file_write_tool, edit, file_edit, file_edit_tool
Shell executionbash, exec, shell, terminal
Git writesgit_commit, git_push, git_merge
Docker writesdocker_run, docker_build, docker_exec
API callshttp_post, http_put, http_delete, api_call
Systeminstall, uninstall, deploy
Agentbotprovision, configure, restart

Shell command introspection

For bash, exec, and shell tools, the classifier inspects the command input to determine the actual concurrency class. Read-only shell commands are promoted to readonly:
CategoryCommands
Filesystem readcat, head, tail, ls, find, stat, wc, du, df
Text processinggrep, sort, uniq, cut, awk
Git read-onlygit status, git diff, git log, git show, git branch, git tag, git remote, git blame, git reflog
System infoecho, pwd, whoami, date, uptime, hostname, env, which
Package infonpm list, npm view, npm outdated, pip list, pip show
Docker read-onlydocker ps, docker images, docker logs, docker inspect, docker stats
HTTP readcurl (without -X, --request, or -d flags)
Shell commands not in this list are classified as mutating.

Partitioning rules

The partitioner groups tool calls into execution batches using these rules:
  1. Consecutive read-only tools become a single parallel batch
  2. Each mutating tool gets its own serial batch
  3. Two adjacent mutating tools are placed in separate serial batches (they do not merge)

Example

Given tools: [read, grep, bash("cat file"), write, read, bash("git push")] The partitioner produces:
BatchTypeToolsExecution
1Parallelread, grep, bash("cat file")All three run simultaneously
2SerialwriteRuns alone after batch 1 completes
3ParallelreadRuns after batch 2 completes
4Serialbash("git push")Runs alone after batch 3 completes
The bash("cat file") command is promoted to readonly via shell command introspection, so it joins the first parallel batch. The read at position 5 starts a new parallel batch because the preceding write forced a serial boundary.