Developer docs · REST API

Build AI + human workflow products on top of Orchflow.

These docs cover the practical flow: register, start a run, inspect tasks, pause for human input, resume, and optionally attach your own provider key.

Quickstart

From zero to first run

The fastest path is: register, start a run, then add a provider later if you need more control.

If you are evaluating Orchflow for the first time, use the hosted flow first. That lets you see task planning, human checkpoints, and run completion before you spend time on provider setup.

1. Register

Create an account and receive an API key once.

2. Start a run

Use the hosted flow first with the managed trial runs.

3. Resume human tasks

When Orchflow pauses, send the human response and continue execution.

What this does: starts one tracked run. Replace orch_your_key, keep the built-in agent names, and edit ask_me_about to the facts your app should collect from the user.

curl -X POST https://api.orchflow.cloud/api/v1/runs \
  -H "X-API-Key: orch_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Plan and launch a faceless YouTube channel about AI tools for freelancers.",
    "agents": [
      { "name": "research" },
      { "name": "analyst" },
      { "name": "writer" }
    ],
    "ask_me_about": ["brand voice", "target audience"],
    "require_approval": false
  }'
After you receive run_id

The loop is only three moves: poll the run, answer a waiting human task if Orchflow asks, then poll again until status is completed.

# 1. Inspect the run
curl https://api.orchflow.cloud/api/v1/runs/run_abc123 \
  -H "X-API-Key: orch_your_key"

# 2. If status is waiting_human, answer that task
curl -X POST https://api.orchflow.cloud/api/v1/runs/run_abc123/tasks/T1/complete \
  -H "X-API-Key: orch_your_key" \
  -H "Content-Type: application/json" \
  -d '{"output":"Company: a workflow API for AI apps. Brand voice: direct, useful, technical."}'

# 3. Poll the same run again to watch AI continue
curl https://api.orchflow.cloud/api/v1/runs/run_abc123 \
  -H "X-API-Key: orch_your_key"
Authentication

How API keys work

Orchflow returns a raw API key once at registration time. After that, only the hash is stored.

Registration is intentionally lightweight. Orchflow returns the raw API key once, and every protected route after that expects it in the request header.

POST /api/v1/auth/register
Creates a new account and returns an API key. Pass that key on later requests as the `X-API-Key` header.
{
  "name": "Tarun",
  "email": "tarun@example.com"
}
curl -X POST https://api.orchflow.cloud/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Tarun","email":"tarun@example.com"}'
Header Value Required
X-API-Key Your Orchflow API key Yes, for protected routes
Runs API

Start, inspect, and cancel runs

The runs API is the heart of Orchflow. One request starts a workflow and returns a `run_id` immediately.

Think of a run as the top-level workflow container. You send one goal, Orchflow creates the task graph, executes what it can, and keeps the full run state available while work is in progress.

POST /api/v1/runs
Starts a new orchestration run in the background.
{
  "task": "Research 5 competitors, extract pricing, compare positioning, then propose our launch strategy.",
  "ask_me_about": ["company details"],
  "require_approval": false
}
curl -X POST https://api.orchflow.cloud/api/v1/runs \
  -H "X-API-Key: orch_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "task":"Research 5 competitors, extract pricing, compare positioning, then propose our launch strategy.",
    "ask_me_about":["company details"],
    "require_approval":false
  }'
GET /api/v1/runs
Returns paginated run history for the authenticated account.
curl 'https://api.orchflow.cloud/api/v1/runs?limit=10&offset=0' \
  -H "X-API-Key: orch_your_key"
GET /api/v1/runs/{id}
Returns current run status, subtask tree, and final output if available.
curl https://api.orchflow.cloud/api/v1/runs/run_abc123 \
  -H "X-API-Key: orch_your_key"
GET /api/v1/runs/{id}/tasks
Returns all subtasks. Works mid-run thanks to progressive task persistence.
curl https://api.orchflow.cloud/api/v1/runs/run_abc123/tasks \
  -H "X-API-Key: orch_your_key"
DELETE /api/v1/runs/{id}
Cancels a run that is still active.
curl -X DELETE https://api.orchflow.cloud/api/v1/runs/run_abc123 \
  -H "X-API-Key: orch_your_key"
Human-in-loop

Resume tasks when Orchflow pauses

When a task needs human input, the run moves to `waiting_human`. Submit the answer and the run continues automatically.

Human tasks are what make Orchflow useful for real products. When the workflow needs brand context, approval, or judgment, it pauses instead of hallucinating past the missing information.

POST /api/v1/runs/{id}/tasks/{task_id}/complete
Submits human output for a waiting task.
{
  "output": "Brand voice should be practical and founder-friendly. Target audience is solo freelancers and small agencies."
}
curl -X POST https://api.orchflow.cloud/api/v1/runs/run_abc123/tasks/T1/complete \
  -H "X-API-Key: orch_your_key" \
  -H "Content-Type: application/json" \
  -d '{"output":"Company details: we build workflow APIs. Brand voice: direct and technical."}'
  • Use `ask_me_about` when you want Orchflow to explicitly ask for missing context.
  • Use `human_gates` when you want to route matching tasks to humans.
  • Use `require_approval=true` when every task must wait for human approval.
Providers

Register and manage LLM providers

Provider keys are encrypted before storage. The raw key is never returned after registration.

Providers are optional for the first managed trial runs in hosted mode. After that, use `provider_id` in `POST /runs` so Orchflow knows which model account to execute against.

POST /api/v1/providers
Registers a provider and returns a `provider_id`.
{
  "provider": "gemini",
  "api_key": "your_provider_key",
  "label": "My Gemini key",
  "model": "gemini-3.1-flash-lite-preview"
}
GET /api/v1/providers
Lists all active providers for the authenticated account.
curl https://api.orchflow.cloud/api/v1/providers \
  -H "X-API-Key: orch_your_key"
DELETE /api/v1/providers/{provider_id}
Deactivates a provider so future runs can no longer use it.
curl -X DELETE https://api.orchflow.cloud/api/v1/providers/prv_abc123 \
  -H "X-API-Key: orch_your_key"
BYOK flow

Use this after the managed trial, or whenever you want your own model account. Register the provider once. Orchflow stores the encrypted key and returns a provider_id. Future runs use that id, not the raw provider key.

# 1. Register your provider key once
curl -X POST https://api.orchflow.cloud/api/v1/providers \
  -H "X-API-Key: orch_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "gemini",
    "api_key": "your_gemini_api_key",
    "label": "My Gemini key",
    "model": "gemini-2.0-flash-lite"
  }'

# Response:
# { "provider_id": "prv_abc123", ... }

# 2. Pass provider_id when starting a run
curl -X POST https://api.orchflow.cloud/api/v1/runs \
  -H "X-API-Key: orch_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "task": "Research competitors and draft a launch strategy.",
    "provider_id": "prv_abc123",
    "agents": [{ "name": "research" }, { "name": "writer" }],
    "ask_me_about": ["company details"],
    "require_approval": false
  }'
Agent templates

Use built-in named agents

For the fastest first run, you can pass agent names only and let Orchflow fill the built-in templates.

Built-in templates are the fastest path for first runs. You can pass only the agent names and let Orchflow fill the system prompts automatically.

GET /api/v1/agents/templates
Returns the built-in agent templates and their recommended use cases.
curl https://api.orchflow.cloud/api/v1/agents/templates
{
  "agents": [
    { "name": "research" },
    { "name": "analyst" },
    { "name": "writer" }
  ]
}
Implementation

Embed Orchflow into your own app

Most teams will call Orchflow from their backend, persist the `run_id` in their own database, and show progress or approval steps in their own UI.

The usual pattern is simple: your app starts a run, stores the returned `run_id`, polls or listens for status changes, and submits human responses when Orchflow pauses.

Start from your backend

Use your server to call Orchflow so your app controls when workflows begin and how the resulting `run_id` is stored.

Show progress in your UI

Read `GET /runs/{id}` or `GET /runs/{id}/tasks` and render task states in your own product interface.

Resume after human input

When a run pauses, your UI can capture approval or missing context and pass it back through the task completion endpoint.

Python backend example

This is the important developer loop. Start a run, poll task progress, print what Orchflow is doing, and stop with a clear task_id when the workflow needs human input.

Python
import time
import requests

API = "https://api.orchflow.cloud/api/v1"
api_key = "orch_your_key"
headers = {"X-API-Key": api_key}


def orchflow(method, path, **kwargs):
    response = requests.request(method, f"{API}{path}", headers=headers, timeout=60, **kwargs)
    if not response.ok:
        raise RuntimeError(f"Orchflow {response.status_code}: {response.text}")
    return response.json()


run = orchflow("POST", "/runs", json={
    "task": "Research competitors, compare pricing, then draft our launch strategy.",
    "agents": [{"name": "research"}, {"name": "analyst"}, {"name": "writer"}],
    "ask_me_about": ["company details", "brand voice"],
    "require_approval": False
})

run_id = run["run_id"]
print("Started run:", run_id)

while True:
    run = orchflow("GET", f"/runs/{run_id}")
    print("\nRun status:", run["status"])

    for task_id, task in run["subtasks"].items():
        print(f"{task_id}: {task['state']} - {task['name']}")

    waiting = [
        (task_id, task)
        for task_id, task in run["subtasks"].items()
        if task["state"] == "waiting_human"
    ]

    if waiting:
        task_id, task = waiting[0]
        print(f"\nAction needed: answer task {task_id} - {task['name']}")
        break

    if run["status"] in ["completed", "failed", "cancelled"]:
        print("\nFinal output:", run.get("final_output"))
        break

    time.sleep(3)
Resume a human task

Run this when the watcher prints Action needed. Replace T1 with the printed task id. After this POST succeeds, run the watcher again or keep polling from your app.

Python
import requests

api_key = "orch_your_key"
run_id = "run_abc123"
task_id = "T1"

response = requests.post(
    f"https://api.orchflow.cloud/api/v1/runs/{run_id}/tasks/{task_id}/complete",
    headers={"X-API-Key": api_key},
    json={
        "output": "Company: a workflow API for AI apps. Brand voice: direct, useful, technical."
    },
    timeout=30
)

response.raise_for_status()
print("Submitted human input. Continue polling the run.")
Frontend polling example

For a production app, proxy this through your backend. This minimal browser example shows the polling shape, but keeping API keys in a server session is safer than embedding them in client code.

JavaScript
const res = await fetch(`https://api.orchflow.cloud/api/v1/runs/${runId}`, {
  headers: { "X-API-Key": apiKey }
});

const run = await res.json();

if (run.status === "waiting_human") {
  // Show approval form or collect missing context in your UI
}
Errors

Common responses

These are the most common API responses you should expect during development.

Most development issues come from missing API keys, consumed trial runs, invalid payloads, or polling too aggressively. The table below covers the usual fixes.

Status Meaning Typical fix
401 Missing or invalid API key Pass a valid `X-API-Key` header
402 Managed trial runs used up or BYOK required Register a provider and pass `provider_id`
404 Run, task, or provider not found Check the ID and ownership
422 Validation error Check body shape, prompt fields, and required values
429 Rate limit exceeded Retry later or slow down polling
Examples

Good first tasks to try

Use tasks where Orchflow can show planning, routing, human checkpoints, and synthesis clearly.

The best demos are tasks with clear planning value: some parallel work, one or two human checkpoints, and a final output that is obviously stronger than a one-shot model response.

Content workflow

Research, writing, editing, then final approval before publishing.

Competitor analysis

Extract pricing, compare positioning, ask for company context, then produce strategy.

Architecture planning

Design the system, review security/billing risks, and produce an implementation roadmap.

{
  "task": "Plan and launch a faceless YouTube channel about AI tools for freelancers. Research 5 competing channels, extract their content patterns, define our positioning, decide the branding direction, design a 30-day content plan, and produce a launch checklist.",
  "agents": [
    { "name": "research" },
    { "name": "analyst" },
    { "name": "writer" }
  ],
  "ask_me_about": ["brand voice", "target audience", "content constraints"],
  "require_approval": false
}