Quick Start
Choose the current-main local Studio path for the shortest setup, or use the stable 0.7.1 server/API path below when you need a released artifact.
orch8 init my-projectthen orch8 dev my-project. The CLI starts a persistent SQLite-backed Studio at http://localhost:8080, watches the project for changes, and avoids the manual API bootstrap below. This behavior is not yet in the 0.7.1 release.orch8 init my-project
orch8 dev my-project
# One-shot CI smoke test
orch8 dev my-project --no-server --skip-timers --once1. Install
Recommended for macOS and Linux: use the release installer. It verifies the archive checksum before installing. Current main also publishes a native Windows binary and a checksum-verifying PowerShell installer; stable 0.7.1 Windows users should use Docker Desktop or WSL 2.
# macOS / Linux — one-line install
curl -fsSL https://raw.githubusercontent.com/orch8-io/engine/main/install.sh | sh
# macOS — Homebrew alternative
brew install orch8-io/orch8/orch8-server
# Install just the CLI (Go)
brew install orch8-io/orch8/orch8-cli
# SDKs
npm install @orch8.io/sdk # Node.js / TypeScript
pip install orch8-io-sdk # Python
go get github.com/orch8-io/sdk-go # GoPrefer a manual, auditable install? Download the release archive and.tar.gz.sha256 checksum file from GitHub Releases. In the download directory, run sha256sum -c <archive>.sha256(or shasum -a 256 -c <archive>.sha256 on macOS), then extract the archive and place the binary on PATH.
2. Start the engine and verify it
By default the engine requires an API key. For local development, use --insecure to skip authentication:
# Run the binary directly (local development only)
ORCH8_STORAGE_BACKEND=sqlite ORCH8_DATABASE_URL=./orch8-quickstart.db orch8-server --insecure &
# Verify: a healthy engine returns HTTP 200
curl --fail -i http://localhost:8080/health/ready
# Alternative: Docker Desktop — stop the native process before using the same ports
docker run -d -p 127.0.0.1:8080:8080 -p 127.0.0.1:50051:50051 \
ghcr.io/orch8-io/engine:0.7.1 --insecure--insecure disables authentication. Never expose that process to a public or shared network.Choose either the native process or Docker. The native command stores workflow state in ./orch8-quickstart.db in your working directory.
Expected response: HTTP 200; the readiness response has no JSON body. If the command is not found, add~/.local/bin to PATH. If port 8080 is busy, stop the existing process or set ORCH8_HTTP_ADDR=127.0.0.1:18080 to a free address.
For production, generate separate random encryption and API keys:
export ORCH8_ENCRYPTION_KEY="$(openssl rand -hex 32)"
export ORCH8_API_KEY="$(openssl rand -hex 32)"
docker run -d \
-e ORCH8_API_KEY \
-e ORCH8_ENCRYPTION_KEY \
-e ORCH8_STORAGE_BACKEND=postgres \
-e ORCH8_DATABASE_URL=postgres://user:pass@host:5432/orch8 \
-e ORCH8_RUN_MIGRATIONS=true \
-p 8080:8080 -p 50051:50051 \
ghcr.io/orch8-io/engine:0.7.1SQLite initializes its embedded schema automatically. PostgreSQL migrations are opt-in; set ORCH8_RUN_MIGRATIONS=truefor a controlled migration job or first start. HTTP listens on port 8080 and gRPC on 50051 by default.
Product endpoints are canonical under /api/v1, as used below. Bare product routes remain compatibility aliases. Send X-Tenant-Id: demo on product API requests, including local requests made with authentication disabled.
3. Define a sequence
A sequence is a reusable recipe. This zero-dependency example logs two messages, so it works without an external service or credentials.
Keep the SDK client and returned IDs for subsequent steps in the same program. Node.js examples use ES modules with top-level await. Run Python snippets inside an async function (started with asyncio.run) or a notebook that supports top-level await. Add later Go snippets inside the same main function.
curl -X POST http://localhost:8080/api/v1/sequences \
-H "X-Tenant-Id: demo" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "demo",
"namespace": "default",
"name": "hello-world",
"version": 1,
"id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2026-07-28T00:00:00Z",
"blocks": [
{
"type": "step",
"id": "send_greeting",
"handler": "log",
"params": {
"message": "Hello, {{context.data.name}}!"
}
},
{
"type": "step",
"id": "log_done",
"handler": "log",
"params": {
"message": "Greeting sent to {{context.data.name}}"
}
}
]
}'
# Expected: the response includes the id supplied above.
# {"id":"550e8400-e29b-41d4-a716-446655440000", ...}The cURL example supplies a stable sequence ID. Keep it in a shell variable for the next step:
export SEQUENCE_ID="550e8400-e29b-41d4-a716-446655440000"4. Schedule a task instance
An instance is one execution of a sequence. Pass in the context data (in this case, a name) and the engine will run the sequence:
curl -X POST http://localhost:8080/api/v1/instances \
-H "X-Tenant-Id: demo" \
-H "Content-Type: application/json" \
-d '{
"sequence_id": "'"$SEQUENCE_ID"'",
"tenant_id": "demo",
"namespace": "default",
"context": {
"data": { "name": "Alice" }
}
}'
# Copy the actual id from the response before checking status.
export INSTANCE_ID="<id-from-the-create-instance-response>"The engine runs the first step immediately, then the second. Even if you restart the engine mid-run, it will resume from the last completed step.
5. Check the status
# Get instance state
curl -H "X-Tenant-Id: demo" "http://localhost:8080/api/v1/instances/$INSTANCE_ID"
# See step outputs
curl -H "X-Tenant-Id: demo" "http://localhost:8080/api/v1/instances/$INSTANCE_ID/outputs"6. Control a running workflow
The two log steps usually finish before you reach this section. Use the commands below with an instance that is still running or waiting, replacing its ID. These controls do not restart a completed instance. See the signals reference for supported lifecycle operations.
# Pause the instance
curl -X POST "http://localhost:8080/api/v1/instances/$INSTANCE_ID/signals" \
-H "X-Tenant-Id: demo" \
-H "Content-Type: application/json" \
-d '{ "signal_type": "pause" }'
# Resume it
curl -X POST "http://localhost:8080/api/v1/instances/$INSTANCE_ID/signals" \
-H "X-Tenant-Id: demo" \
-H "Content-Type: application/json" \
-d '{ "signal_type": "resume" }'
# Update context mid-run
curl -X POST "http://localhost:8080/api/v1/instances/$INSTANCE_ID/signals" \
-H "X-Tenant-Id: demo" \
-H "Content-Type: application/json" \
-d '{
"signal_type": "update_context",
"payload": { "replied": true }
}'That's it. The engine handles crash recovery, retries, rate limits, and timezone-aware scheduling automatically.
Delay values such as delay.duration are milliseconds;10000 means 10 seconds. Continue with the CLI reference for interactive status, logs, and validation commands.
What's next
Defining Sequences
Block types, delays, and context access
Built-in Handlers
http_request, log, sleep, llm_call
REST API
Guide + generated OpenAPI
Core Concepts
How the engine works under the hood
CLI Reference
Validate, inspect, and control workflows
Ready to try Orch8?
One command to install. Then run your first local sequence.
curl -fsSL https://orch8.io/start.sh | sh