Orch8 Cloud API
Orch8 Cloud is the managed control plane for the Orch8 workflow engine. It provides hosted engine instances, a deployment system for templates, real-time observability, and a multi-strategy gateway for external access.
Cloud vs. Self-Hosted
- ✓This page documents the Cloud management and gateway APIs (base URL
cloud.orch8.io). - ✓Engine API documented at /docs/api covers the self-hosted engine (base URL
localhost:8080or your own domain). - ✓When using Cloud, the engine API is proxied through the Tunnel or Gateway endpoints described below.
Base URL
All Cloud API requests use https://cloud.orch8.io as the base URL. The engine itself is not exposed directly — every call routes through the Cloud proxy layer.
# Management API (session auth)
GET https://cloud.orch8.io/api/instances
POST https://cloud.orch8.io/api/deployments
# Engine proxy (gateway auth)
POST https://cloud.orch8.io/api/tunnel/{instanceId}/sequences
POST https://cloud.orch8.io/api/gateway/{instanceId}/{slug}Authentication
Cloud supports four authentication strategies. The right one depends on whether you are calling the management API (dashboard/automation) or the engine proxy (runtime access).
Dashboard Session
Management endpoints (/api/instances, /api/deployments, etc.) require a valid Supabase session cookie. These are used by the dashboard UI and server-side automation running in your authenticated environment.
Unauthenticated requests return 401 Unauthorized.
API Key
API keys are the simplest way to authenticate engine proxy requests. Create a key in the dashboard under Settings → API Keys. Keys are scoped to an org and optionally to a single instance.
curl https://cloud.orch8.io/api/tunnel/inst_abc123/sequences \
-H "Authorization: Bearer orc8_live_xxxxxxxxxxxxxxxx"Key prefixes:
orc8_live_— production key with full accessorc8_test_— test key (same permissions, for environment separation)
Revoked keys return 401 Unauthorized immediately.
OIDC / JWT
For CI/CD and service-to-service auth, configure an OIDC provider on your instance gateway. Cloud verifies the JWT against the provider's discovery document and enforces claim-based allow rules.
Supported providers:
- GitHub Actions —
https://token.actions.githubusercontent.com - GitLab CI —
https://gitlab.com - Google Cloud —
https://accounts.google.com - Azure —
https://login.microsoftonline.com/{tenant}/v2.0 - CircleCI —
https://oidc.circleci.com/org/{org-id} - Terraform Cloud —
https://app.terraform.io - Generic OIDC — any compliant provider
# GitHub Actions example
curl https://cloud.orch8.io/api/tunnel/inst_abc123/sequences \
-H "Authorization: Bearer $ID_TOKEN"Anonymous
Enable the anonymous provider on a gateway policy to allow unauthenticated access. Useful for public webhooks or health checks. Anonymous requests are tagged with provider anonymous and subject anon.
Instances
An instance is a managed Orch8 engine running on Fly.io infrastructure. Instances are scoped to your organization and region.
List Instances
Returns all non-deleted instances in your org.
200[
{
"id": "inst_abc123",
"name": "production",
"region": "iad",
"status": "running",
"connection_url": "https://...",
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T10:00:00Z"
}
]Create Instance
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | 2–32 chars, must start with a letter or digit, lowercase letters/digits/hyphens only |
| region | string | Yes | gru, iad, fra, sjc, nrt |
Name must match /^[a-z0-9][a-z0-9-]{1,31}$/.
{
"id": "inst_abc123",
"status": "provisioning",
"error": null
}The error field is optional and present only when provisioning fails. Creating an instance can also return:
402— Plan limit reached409— Instance name already exists500— Internal provisioning error
Get Instance
{
"id": "inst_abc123",
"name": "production",
"region": "iad",
"status": "running",
"connection_url": "https://...",
"created_at": "2024-01-15T10:00:00Z"
}Suspend & Resume
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| action | string | Yes | "suspend" or "resume" |
Suspend stops the machine but preserves state. Resume restarts it. While suspended, the instance does not count against your running instance quota.
200// Suspend response
{
"status": "suspended"
}
// Resume response
{
"status": "running"
}Returns 409 Conflict if the instance is not in the expected state (e.g., suspending an instance that is not running).
Delete Instance
Soft-deletes the instance. The Fly machine is destroyed and the instance record is marked deleted. This action is irreversible.
Health Check
Proxies to the engine health endpoint. Returns the engine status and version.
200Engine Proxy
The Cloud proxy layer forwards authenticated requests to your managed engine instance. This is how you use the engine API without exposing the instance directly.
Tunnel API
The Tunnel is a transparent pass-through to the engine. Any HTTP method is supported. Authentication follows the gateway policy system.
curl https://cloud.orch8.io/api/tunnel/inst_abc123/sequences \
-H "Authorization: Bearer orc8_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "acme",
"namespace": "default",
"name": "welcome-campaign",
"definition": { "blocks": [...] }
}'The proxy injects x-gateway-provider andx-gateway-subject headers so the engine can identify the caller.
Gateway API
The Gateway is a named endpoint protected by a gateway policy. Unlike the Tunnel, the Gateway requires a policy slug to exist and verifies authentication against that specific policy before proxying to/webhooks/{slug} on the engine.
curl https://cloud.orch8.io/api/gateway/inst_abc123/stripe-webhook \
-X POST \
-H "Authorization: Bearer orc8_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "type": "payment_intent.succeeded" }'If no policy exists for the slug, the Gateway returns404 Not Found. If authentication fails, it returns401 Unauthorized.
Gateway Policies
Gateway policies control who can access your engine through the Cloud proxy. Each policy is tied to an instance and optionally to a slug. Policies support claim-based allow rules for fine-grained access control.
List Policies
{
"items": [
{
"id": "pol_abc123",
"instance_id": "inst_abc123",
"slug": "stripe-webhook",
"provider": "api-key",
"allow": [],
"config": {},
"enabled": true,
"created_at": "2024-01-15T10:00:00Z"
}
]
}Create Policy
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| slug | string | null | No | Gateway slug. Null = catch-all policy. |
| provider | string | Yes | api-key, anonymous, github-oidc, gitlab-oidc, gcp-oidc, azure-oidc, circleci-oidc, terraform-oidc, bitbucket-oidc, oidc |
| audience | string | null | No | JWT audience claim (for OIDC) |
| issuer | string | null | No | JWT issuer override (for generic oidc) |
| allow | array | No | Claim-based allow rules (see below) |
| config | object | No | Provider-specific config (e.g. tenant, workspace, org_id) |
| enabled | boolean | No | Default: true |
{
"id": "pol_abc123",
"slug": "stripe-webhook",
"provider": "api-key",
"allow": [],
"config": {},
"enabled": true
}Update Policy
Partial update. Only included fields are changed.
{
"enabled": false,
"allow": [{ "sub": "user-123" }]
}Delete Policy
Allow Rules
The allow array contains OR-rules. Each rule is an object of AND-conditions. A request matches if any rule matches, and a rule matches only if all its conditions match.
// Allow any request (default when allow is empty)
[]
// Allow only a specific JWT subject
[{ "sub": "user-123" }]
// Allow multiple subjects
[{ "sub": "user-123" }, { "sub": "user-456" }]
// Allow specific GitHub repository
[{ "sub": "repo:myorg/myrepo:ref:refs/heads/main" }]
// Allow multiple claims (AND within rule)
[{ "sub": "user-123", "iss": "https://accounts.google.com" }]
// Allow any subject from a specific org (array = OR within field)
[{ "org_id": ["org-123", "org-456"] }]Available claims depend on the provider. API keys exposesub (the key prefix) and org_id. OIDC providers expose all JWT claims (sub, iss, aud, and provider-specific claims).
Deployments
Deployments define the combination of a template and its runtime configuration. Creating a deployment is the primary way to start a managed workflow on Orch8 Cloud.
List Deployments
[
{
"id": "dep_abc123",
"name": "onboarding-v2",
"status": "running",
"engine_instance_id": "inst_abc123",
"webhook_url": "https://cloud.orch8.io/api/gateway/inst_abc123/...",
"created_at": "2024-01-15T10:00:00Z"
}
]Create Deployment
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| template_id | string | Yes | Template ID to deploy |
| name | string | No | Deployment name (unique within org) |
| config | object | No | Runtime configuration |
| secrets | object | No | Secret values |
curl https://cloud.orch8.io/api/deployments \
-X POST \
-H "Authorization: Bearer orc8_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tmpl_abc123",
"name": "onboarding-v2",
"config": { "timeout": 30 },
"secrets": { "api_key": "sk-..." }
}'{
"id": "dep_abc123",
"status": "provisioning",
"engine_instance_id": "inst_abc123",
"webhook_url": "https://cloud.orch8.io/api/gateway/inst_abc123/..."
}Can return 402 (plan too low), 400 (no instance or engine unreachable), or 502 (engine error).
Deployment Actions
Delete removes the deployment and destroys the underlying instance. Suspend and resume are not supported at the deployment level; use instance lifecycle actions instead.
204Management
API Keys
Create and manage API keys for engine proxy access. Keys are generated in the dashboard under Settings → API Keys.
orc8_live_— production keysorc8_test_— test/development keys
Both prefixes have identical permissions. Use them to separate environments (production vs. staging vs. development).
Organization
All Cloud resources are scoped to an organization. Users are members of orgs via Supabase auth. The org ID is extracted from the session and used for all instance, deployment, and policy queries.
Alerts
Configure a single org-wide webhook alert.
{
"org_id": "org_abc123",
"webhook_url": "https://hooks.slack.com/services/...",
"enabled": true,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T10:00:00Z"
}Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| webhook_url | string | No | HTTPS URL (or HTTP localhost). Max 2048 chars. |
| enabled | boolean | No | Cannot be enabled without a webhook_url |
Requires admin privileges. Only included fields are changed. The webhook URL must use https (or http://localhost) and cannot exceed 2048 characters.
Usage & Quotas
Returns the current billing period usage against your plan limits.
curl https://cloud.orch8.io/api/usage/current \
-H "Authorization: Bearer orc8_live_xxxxxxxxxxxxxxxx"{
"period_start": "2024-01-01T00:00:00Z",
"period_end": "2024-01-31T23:59:59Z",
"executions": 45200,
"quota": 100000,
"pct": 45.2
}quota is null for unlimited plans and pct isnull when there is no quota limit.
Billing
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| plan | string | Yes | "starter" or "pro" |
{
"url": "https://checkout.stripe.com/..."
}Returns 503 if billing is disabled, 403 if the caller is not the owner or an admin.
Opens the Stripe Customer Portal to manage subscriptions.
200{
"url": "https://billing.stripe.com/..."
}Returns 400 if no Stripe customer exists for the organization.
Reference
Error Responses
| Status | Meaning |
|---|---|
| 400 | Bad Request — invalid body, no instance, or engine unreachable |
| 401 | Unauthorized — no valid auth (session or gateway) |
| 402 | Payment Required — plan limit or plan too low |
| 403 | Forbidden — auth succeeded but insufficient permissions |
| 404 | Not Found — instance, policy, or deployment does not exist |
| 409 | Conflict — instance name already exists, or state conflict |
| 422 | Unprocessable — gateway policy validation failed |
| 429 | Rate Limited — too many requests |
| 500 | Internal Error — contact support |
| 502 | Bad Gateway — engine error |
| 503 | Service Unavailable — billing disabled |
Regions
Orch8 Cloud runs on Fly.io. Available regions:
| Region | Location |
|---|---|
| gru | São Paulo (BR) |
| iad | Washington, DC (US) |
| fra | Frankfurt (DE) |
| sjc | San Jose, CA (US) |
| nrt | Tokyo (JP) |