API Reference

June 10, 2026 · View on GitHub

All endpoints except those marked (public) require Authorization: Bearer <token>.

Authentication — password

POST /auth/register         Create account → {token, user}                  (201)
POST /auth/login            Login → {token, user}
POST /auth/logout           Revoke current JWT (jti blocklisted in Redis)
GET  /auth/me               Current user

Passwords must be ≥ 8 characters and contain at least one letter and one digit.

Authentication — SSO / OIDC

Requires OIDC_ENABLED=true in the adapter environment.

GET  /auth/sso/config       (public) Returns enabled providers + login URL
GET  /auth/sso/login        Redirect to OIDC provider authorization endpoint
GET  /auth/sso/callback     OIDC code exchange → JWT + refresh token
POST /auth/token/refresh    Exchange refresh token → new JWT + rotated refresh token

SCIM 2.0

Requires SCIM_BEARER_TOKEN bearer authentication (separate from user JWTs).

GET    /scim/v2/Users           List users (supports userName filter + pagination)
GET    /scim/v2/Users/{id}      Single user
PATCH  /scim/v2/Users/{id}      Deactivate user (RFC 7644 + Okta-style)

Flows

GET    /flows                             List user's flows (paginated)
POST   /flows                             Save / upsert flow (auto-versions)
GET    /flows/{id}                        Current spec
DELETE /flows/{id}                        Delete flow + all versions
GET    /flows/{id}/versions               Version history
POST   /flows/{id}/versions/{v}/restore   Restore a version
POST   /flows/{id}/invoke                 Synchronous execution (deployed flows only)

POST /flows/{id}/invoke returns the result directly when the flow completes (default timeout: 120 s via INVOKE_TIMEOUT_S). Use POST /run + polling for long-running flows or flows with HITL nodes.

Execution

POST /run                   Execute flow async → {job_id}
GET  /run/{job_id}          Job status, node_events, trace_id, trace_url
POST /run/{job_id}/resume   Resume a paused HITL flow

Harness execution endpoints

These endpoints are only relevant for flows with harness_meta.enabled = true.

GET  /runs/{id}/harness-state         Read current HarnessRunState
PUT  /runs/{id}/harness-state         Write updated HarnessRunState
POST /run/{job_id}/escalation/respond Respond to a surface_blocker escalation
GET  /run/concepts                    List all registered process concepts

PUT /runs/{id}/harness-state body

{
  "world_model": { ... },
  "hypothesis_set": { ... },
  "control_state": { ... },
  "task_graph": { ... },
  "evidence_store": { ... },
  "caller_state": { ... },
  "output_contract": { ... }
}

Only the fields provided are updated; absent fields retain their current values.

POST /run/{job_id}/escalation/respond body

{
  "response": "...",
  "updated_constraints": { ... }   // optional — triggers constraint-change propagation
}

Returns { "status": "resumed" } when the harness loop is successfully unblocked.

POST /run body

{
  "spec":    { ... },            // FlowSpec (v1.0.0 — includes optional harness_meta block)
  "input":   { ... },            // optional initial state
  "runtime": "langgraph"         // optional — overrides runtime_hints.preferred_adapter
}

To enable the harness, include harness_meta in the FlowSpec:

{
  "harness_meta": {
    "enabled": true,
    "process_concept_id": "implement_feature",  // optional — seeds task graph from a concept
    "max_steps": 50
  }
}

Job status response

{
  "job_id":      "uuid",
  "status":      "pending | running | paused | completed | failed",
  "node_events": [ { "node_id": "...", "status": "...", "tokens": 0, "ms": 0 } ],
  "trace_id":    "langfuse-trace-id",
  "trace_url":   "http://localhost:3001/trace/...",
  "result":      { ... },        // present when status == completed
  "error":       "...",          // present when status == failed
  "hitl_prompt": { ... }         // present when status == paused
}

POST /run/{job_id}/resume body

{
  "payload": { "decision": "approved", "notes": "LGTM" }
}

Codegen

POST /compile               Spec → code                             (30 req/min)
GET  /runtimes              (public) Available runtimes + NODE_SUPPORT_MATRIX
GET  /health                (public) Adapter status

POST /compile query params

ParamValuesDefault
runtimelanggraph · crewai · mastra · mafruntime_hints.preferred_adapter or langgraph

Response: { "code": "...", "warnings": ["..."] }

Deploy

POST   /deploy/{flow_id}              One-click deploy (REST + MCP + A2A)
DELETE /deploy/{flow_id}              Undeploy all targets
GET    /share/{flow_id}               (public) Public deployment metadata
GET    /.well-known/mcp/{id}.json     (public) MCP tool manifest

POST /deploy/{flow_id} returns:

{
  "rest_url":      "http://adapter:8000/flows/my-flow/invoke",
  "mcp_url":       "http://adapter:8000/.well-known/mcp/my-flow.json",
  "a2a_url":       "http://adapter:8000/a2a/my-flow/tasks/send",
  "shareable_url": "http://adapter:8000/share/my-flow"
}

A2A protocol

POST   /deploy/a2a/{flow_id}                      Deploy as A2A agent only
DELETE /deploy/a2a/{flow_id}                      Undeploy A2A only
GET    /.well-known/agent/{id}.json               (public) AgentCard
POST   /a2a/{flow_id}/tasks/send                  Submit A2A task
GET    /a2a/{flow_id}/tasks/{task_id}             Task status
GET    /a2a/{flow_id}/tasks/{task_id}/events      SSE stream of task events

Marketplace

GET  /marketplace               (public) List components (paginated, filterable)
GET  /marketplace/{slug}        (public) Component detail
POST /marketplace               Publish a component
POST /marketplace/{slug}/install Install → {node_spec, tool_def}

GET /marketplace query params

ParamDescription
qFull-text search across name, description, tags
categoryFilter by category (tool, agent, transform, memory)
sourceFilter by source (npm, pypi, builtin)
page / page_sizePagination (default page_size: 20)

Teams and orgs

# Teams
POST   /teams                       Create team
GET    /teams                       List caller's teams
GET    /teams/{id}                  Team detail + members
PATCH  /teams/{id}                  Rename (admin only)
DELETE /teams/{id}                  Delete (admin only)
POST   /teams/{id}/members          Invite member
PATCH  /teams/{id}/members/{uid}    Change role (admin/editor/viewer)
DELETE /teams/{id}/members/{uid}    Remove member
POST   /teams/{id}/flows/{fid}      Share flow with team (view/edit)
DELETE /teams/{id}/flows/{fid}      Unshare flow
GET    /teams/{id}/flows            List flows shared with team

# Orgs
POST   /orgs                        Create org
GET    /orgs                        List caller's orgs
GET    /orgs/{id}                   Org detail
PATCH  /orgs/{id}                   Update org (admin only)
DELETE /orgs/{id}                   Delete org (admin only)
POST   /orgs/{id}/members           Invite member
PATCH  /orgs/{id}/members/{uid}     Change role
DELETE /orgs/{id}/members/{uid}     Remove member

Every request is scoped to the org identified by the X-Org-ID header (or the caller's personal org if omitted). LangGraph job thread IDs are namespaced as {org_id}:{job_id} — state never bleeds between orgs.

Eval

POST /eval/score        Write LLM-as-judge score to a trace
POST /eval/feedback     User thumbs signal (+1 / -1 / 0)
GET  /eval/templates    Active evaluator configs
GET  /eval/scores       Scores for a trace (query param: trace_id)

Prompts

GET /prompts            List Langfuse-managed prompts
GET /prompts/{name}     Versions + preview for a named prompt

Rate limits

All mutating endpoints are rate-limited via slowapi. Default limits:

Endpoint groupLimit
POST /compile30/min per user
POST /run20/min per user
Auth endpoints (/auth/register, /auth/login, /auth/logout)10/min per IP
All other mutating endpoints60/min per user

Error responses

All errors return JSON:

{
  "detail": "Human-readable error message"
}

Common status codes:

CodeMeaning
400Invalid request body or fn_ref rejected by allowlist
401Missing or expired JWT
403Insufficient team/org role
404Flow, job, or resource not found
409Conflict — e.g. duplicate slug in marketplace
422Pydantic validation error (body shape wrong)
429Rate limit exceeded