Orkestia
Blog
Reference

API & Tooling

The programmatic surfaces for driving Orkestia workflows — the REST API, the typed Node/TS SDK, and the two-token auth model

Orkestia exposes the same workflow engine through four drivers: the typed Node and Python SDKs, a plain HTTP API, and MCP for AI agents. They all wrap one loop — discover → check schema → run → stream → (retry) — over one event-sourced engine, so a run you start from the SDK is the same run you stream over REST or inspect from an agent. End-user login is a separate package: @orkestia/auth (PKCE / OAuth). For the model behind types, runs, and async transitions, see Workflows & runs and the hybrid execution model.

This page documents the programmatic surfaces and their auth. For the input/output schema of any specific workflow, the catalog is the source of truth — browse reference.orkestia.dev or call client.catalog.getSchema() / get_workflow_schema at runtime rather than hard-coding shapes.

The exact request/response shapes below are verified against the SDK contract and the workflow surface. Per-workflow inputs and outputs are not — they vary by type and evolve. Always resolve them from the live schema, not from examples.

The surfaces at a glance

SDKs

@ltinteg/workflows-sdk (Node / TypeScript) and ltinteg-workflows-sdk (Python) — typed clients generated from the same catalog. @orkestia/auth is the browser OAuth SDK for your app's end-users. Full install and examples: SDKs.

REST API

The HTTP surface the SDKs wrap, served at workflow-api.orkestia.dev — start, discover, status, history, and retry. Call it from any language.

MCP

The platform exposed to AI agents: list_workflow_types, get_workflow_schema, start_workflow, watch_workflow, and the rest, callable unattended.

Authentication — the two-token model

Every call carries a bearer token in the Authorization header. There are two kinds, and which one you hold decides what the run can touch.

Org-member tokenEnd-user token
Who holds itYour team operating the platformA user of an app you built on Orkestia
Issued byOrg login (Cognito) or an API tokenSign in with Orkestia (PKCE, RS256 JWT)
Scope of a runThe whole organization's resourcesOnly that user's data within your app
Org resolutionResolved server-side from the tokenResolved server-side; user identity is injected immutably
Typical callerSDKs, CI, MCP agents, dashboardsWorkflows you've exposed to end-users

The critical invariant for both: org-scoping is automatic. Your organization_uuid is resolved from the token server-side and applied to every run — you never pass it in initial_data unless a workflow's schema explicitly declares it (and then it must match your authenticated org). For an end-user token, Orkestia additionally pins the user's identity to the run so it can never reach another user's data. The isolation is the platform's responsibility, not your app's. See Organizations & identity.

# Both tokens are sent the same way — only the issuer and scope differ.
# Introspect the token you hold via GET /api/auth/me.
curl -sS https://workflow-api.orkestia.dev/api/auth/me \
  -H "Authorization: Bearer $ORKESTIA_TOKEN"
# → { "user_id": "...", "organization_uuid": "org_...",
#     "username": "...", "token_type": "...", "principal_type": "..." }
End-user tokens are RS256 JWTs minted by Sign in with Orkestia; org-member tokens come from Cognito org login or are personal API tokens (lt_…), which work in one organization and can be limited to specific workflows. Both are validated server-side and carry the same Authorization: Bearer shape — /api/auth/me reports which kind you're holding via token_type / principal_type.
Still stabilizing. Token issuance, end-user exposure (App Enablement), and rate limits may change between releases. Treat tokens as secrets — keep org-member tokens server-side, and never embed them in a browser app; for browser/end-user flows use Sign in with Orkestia so the app never holds a long-lived credential.

Start a run via REST

The full loop over HTTP. Discovery, schema, start, watch, status, history, and retry are all under /api/workflows.

BASE=https://workflow-api.orkestia.dev/api/workflows
AUTH="Authorization: Bearer $ORKESTIA_TOKEN"

# 1. (optional) discover what's available — the response also carries a
#    `namespaces` summary of the top-level domains (aws, dns, runner, …)
curl -sS "$BASE/types?prefix=aws." -H "$AUTH"

# 2. check the input schema before you run
curl -sS "$BASE/types/aws.s3.create_bucket/schema" -H "$AUTH"
# → { "input_schema": {...}, "output_schema": {...}, "has_prerequisites": true }

# 3. start a run — note: no organization_uuid in the body
curl -sS -X POST "$BASE/start" -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
        "workflow_type": "aws.s3.create_bucket",
        "initial_data": { "bucket": "my-app-assets", "connection_uuid": "…", "region": "us-east-1" }
      }'
# → { "workflow_id": "wf_...", "state_name": "PENDING", "is_terminal": false }

Then track it:

# 4. stream transitions live (Server-Sent Events) until terminal
curl -sN "$BASE/wf_abc123/stream" -H "$AUTH"

# point-in-time run state / full event-sourced history
curl -sS "$BASE/wf_abc123"         -H "$AUTH"
curl -sS "$BASE/wf_abc123/history" -H "$AUTH"

# resume a FAILED run from its last good state
curl -sS -X POST "$BASE/wf_abc123/retry" -H "$AUTH"
EndpointMethodPurpose
/api/workflows/types?prefix=GETList workflow types (filterable by prefix); response includes a namespaces summary
/api/workflows/types/{type}/schemaGETInput/output schema + has_prerequisites
/api/workflows/types/{type}/prerequisitesGETSetup guide when has_prerequisites is true
/api/workflows/startPOSTStart a run → { workflow_id, state_name, is_terminal }
/api/workflows/{id}/streamGET (SSE)Stream transitions until terminal
/api/workflows/{id}GETCurrent run state
/api/workflows/{id}/historyGETFull transition log
/api/workflows/{id}/retryPOSTRe-drive a failed run from its last good state
If has_prerequisites is true (typical for cloud connections), fetch the setup guide first — it returns a step-by-step with Orkestia's platform identity already filled in. See AWS connections and runner management.

Start a run via SDK

The Node/TS SDK wraps the same endpoints. You construct one LtIntegWorkflowsClient, then drive runs either through the manager surface (client.workflows, client.catalog, …) or through the generated, per-workflow bindings — one autocompleted, type-checked binding per workflow, exported as a namespace per domain (aws, github, stripe, …). The flow mirrors REST exactly.

Node — @ltinteg/workflows-sdk
import { LtIntegWorkflowsClient, aws } from "@ltinteg/workflows-sdk"

const client = new LtIntegWorkflowsClient({
  baseUrl: "https://workflow-api.orkestia.dev",
  token: process.env.ORKESTIA_TOKEN,   // org-member or end-user token
})

// discover + inspect via the catalog manager (optional once you know the type)
await client.catalog.listTypes({ prefix: "aws." })
await client.catalog.getSchema("aws.s3.create_bucket")

// start via the generated binding — inputs are typed; organization_uuid is
// resolved from the token, never passed. Returns a WorkflowRunHandle.
const run = await aws.s3.startCreateBucket(client, {
  bucket: "my-app-assets",
  connection_uuid: "…",
  region: "us-east-1",
})
console.log(run.workflowId, run.stateName)

// stream typed events until terminal, or await the terminal output
for await (const evt of run.events()) {
  if (evt.type === "transition") console.log(evt.from, "->", evt.to)
  if (evt.type === "completed") break
  if (evt.type === "failed") throw new Error(evt.error.message)
}
const output = await run.wait()      // resolves to the terminal state_data

// lifecycle off the workflows manager, keyed by workflowId
await client.workflows.get(run.workflowId)
await client.workflows.history(run.workflowId)
await client.workflows.retry(run.workflowId)   // only meaningful for a FAILED run

The client accepts either token kind — pass an org-member token for platform automation, or an end-user token when acting on behalf of a signed-in app user. The surface is identical; the scope is enforced server-side.

The Python SDK (ltinteg-workflows-sdk) is generated from the same catalog and drives the same /api/workflows/* surface. The Node SDK remains the most complete runtime (SSE, run.wait(), typed errors). End-user JWTs come from @orkestia/auth. Browse bindings at reference.orkestia.dev.
Manager methods map one-to-one to the REST endpoints in the table above: client.workflows.get/history/retry/stream, client.catalog.listTypes/getSchema/getDefinition, plus client.plugins and client.projects. The generated bindings are thin wrappers over client.start(...) that add typed inputs/outputs and return a WorkflowRunHandle with .events(), .wait(), and .get().

Choosing a driver

Use…When
Node SDKTypeScript/Node — typed inputs, SSE, run.wait(). See Workflows SDK — Node
Python SDKPython ≥3.10 — same catalog, Pydantic start helpers. See Workflows SDK — Python
@orkestia/authBrowser PKCE / OAuth for your users. See Auth SDK
RESTAnother language, CI, or zero dependencies
MCPAn AI agent operating the catalog — MCP integration

Where to go next

Workflow types registry

The full catalog of workflow domains and types, with per-workflow inputs and outputs.

MCP integration

Drive the same engine from an AI agent — tools, discovery, and the agent loop.

SDKs

Node, Python, and @orkestia/auth — install and examples.

Identity & multi-tenancy

How org-member and end-user tokens scope every run, and how "Sign in with Orkestia" works.

Workflow reference

Every workflow, by domain — the authoritative source for input/output shapes.