Get started
Zero to running workflow in 2 minutes
Install the engine, define a sequence, schedule a task. No JVM, no Cassandra, no Elasticsearch. One binary, one database.
Install
Pick one:
curl -fsSL https://orch8.io/start.sh | shbrew tap orch8-io/orch8 && brew install orch8-serverdocker run -d -p 8080:8080 ghcr.io/orch8-io/engine:latestThe Docker image uses SQLite by default — no external database needed for local development.
Start the engine
By default the engine requires an API key for authentication. For local development, run with --insecure to skip auth:
orch8-server --insecureFor production, set an API key via environment variable:
export ORCH8_API_KEY="your-secret-key"
orch8-serverThe engine runs migrations automatically and starts listening on port 8080. If you used Docker, it's already running.
Note: If the command is not found, make sure the install directory (usually ~/.local/bin) is in your PATH.
For production with Postgres:
docker run -d \
-e ORCH8_STORAGE_BACKEND=postgres \
-e ORCH8_DATABASE_URL=postgres://user:pass@host:5432/orch8 \
-p 8080:8080 \
ghcr.io/orch8-io/engine:latestDefine a sequence
A sequence is a series of steps the engine will execute durably. Create one with a POST request:
curl -X POST http://localhost:8080/sequences \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "demo",
"namespace": "default",
"name": "welcome-flow",
"definition": {
"blocks": [
{
"type": "step",
"id": "send_welcome",
"handler": "http_request",
"params": {
"url": "https://httpbin.org/post",
"method": "POST",
"body": {
"to": "{{context.data.email}}",
"message": "Welcome, {{context.data.name}}!"
}
}
},
{
"type": "step",
"id": "wait_then_followup",
"handler": "log",
"delay": { "duration": "10s" },
"params": {
"message": "Following up with {{context.data.name}}"
}
}
]
}
}'The response returns a sequence ID. Copy it for the next step.
Schedule a task instance
curl -X POST http://localhost:8080/instances \
-H "Content-Type: application/json" \
-d '{
"sequence_id": "<sequence-id-from-step-2>",
"tenant_id": "demo",
"namespace": "default",
"priority": 1,
"context": {
"data": {
"email": "jane@example.com",
"name": "Jane"
}
}
}'The engine picks up the instance, executes the first step immediately, waits 10 seconds, then runs the follow-up. If the engine crashes and restarts, it resumes from the last completed step.
Check the status
# Get instance state
curl http://localhost:8080/instances/<instance-id>
# See step outputs
curl http://localhost:8080/instances/<instance-id>/outputsControl it
# Pause
curl -X POST http://localhost:8080/instances/<instance-id>/signals \
-H "Content-Type: application/json" \
-d '{ "signal_type": "Pause" }'
# Resume
curl -X POST http://localhost:8080/instances/<instance-id>/signals \
-H "Content-Type: application/json" \
-d '{ "signal_type": "Resume" }'
# Cancel
curl -X POST http://localhost:8080/instances/<instance-id>/signals \
-H "Content-Type: application/json" \
-d '{ "signal_type": "Cancel" }'Use an SDK instead of curl
Install an official SDK and manage everything from code:
Node.js / TypeScript
npm install @orch8.io/sdkimport { Orch8Client } from "@orch8.io/sdk";
const client = new Orch8Client({ baseUrl: "http://localhost:8080" });
// Create a sequence
const seq = await client.sequences.create({
tenantId: "demo",
namespace: "default",
name: "welcome-flow",
definition: {
blocks: [
{
type: "step",
id: "greet",
handler: "log",
params: { message: "Hello, {{context.data.name}}!" },
},
],
},
});
// Schedule an instance
const instance = await client.instances.create({
sequenceId: seq.id,
tenantId: "demo",
namespace: "default",
context: { data: { name: "Jane" } },
});
console.log("Instance:", instance.id);Python
pip install orch8-io-sdkfrom orch8 import Orch8Client
client = Orch8Client(base_url="http://localhost:8080")
seq = client.sequences.create(
tenant_id="demo",
namespace="default",
name="welcome-flow",
definition={
"blocks": [{
"type": "step",
"id": "greet",
"handler": "log",
"params": {"message": "Hello, {{context.data.name}}!"},
}]
},
)
instance = client.instances.create(
sequence_id=seq.id,
tenant_id="demo",
namespace="default",
context={"data": {"name": "Jane"}},
)
print(f"Instance: {instance.id}")Go
go get github.com/orch8-io/sdk-gopackage main
import (
"context"
"fmt"
orch8 "github.com/orch8-io/sdk-go"
)
func main() {
client := orch8.NewClient("http://localhost:8080")
ctx := context.Background()
seq, _ := client.Sequences.Create(ctx, &orch8.CreateSequenceInput{
TenantID: "demo",
Namespace: "default",
Name: "welcome-flow",
Definition: map[string]interface{}{
"blocks": []map[string]interface{}{{
"type": "step",
"id": "greet",
"handler": "log",
"params": map[string]interface{}{"message": "Hello!"},
}},
},
})
inst, _ := client.Instances.Create(ctx, &orch8.CreateInstanceInput{
SequenceID: seq.ID,
TenantID: "demo",
Namespace: "default",
})
fmt.Println("Instance:", inst.ID)
}What next?
Full documentation
Complete API reference, block types, handlers, and configuration
22 real-world patterns
Payment failover, email campaigns, AI agents, circuit breakers
Starter templates
SaaS onboarding, AI support triage, invoice processing
SDKs & CLI
Node.js, Python, Go SDKs and the orch8 CLI
GitHub
Source code, issues, and contributing