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.

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
  }'
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"
}
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.",
  "human_gates": ["pricing", "launch strategy"],
  "require_approval": false
}
GET /api/v1/runs
Returns paginated run history for the authenticated account.
GET /api/v1/runs/{id}
Returns current run status, subtask tree, and final output if available.
GET /api/v1/runs/{id}/tasks
Returns all subtasks. Works mid-run thanks to progressive task persistence.
DELETE /api/v1/runs/{id}
Cancels a run that is still active.
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."
}
  • 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.
DELETE /api/v1/providers/{provider_id}
Deactivates a provider so future runs can no longer use it.
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.
{
  "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
Python
import requests

api_key = "orch_your_key"

run = requests.post(
    "https://api.orchflow.cloud/api/v1/runs",
    headers={"X-API-Key": api_key},
    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
    }
).json()

run_id = run["run_id"]
Resume a human task
Python
import requests

requests.post(
    f"https://api.orchflow.cloud/api/v1/runs/{run_id}/tasks/T1/complete",
    headers={"X-API-Key": api_key},
    json={
        "output": "Target audience is solo freelancers. Brand voice should be practical and founder-friendly."
    }
)
Frontend polling example
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
}