Skip to content

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.

0

Install

Pick one:

curl -fsSL https://orch8.io/start.sh | sh
brew tap orch8-io/orch8 && brew install orch8-server
docker run -d -p 8080:8080 ghcr.io/orch8-io/engine:latest

The Docker image uses SQLite by default — no external database needed for local development.

1

Start the engine

By default the engine requires an API key for authentication. For local development, run with --insecure to skip auth:

Local development (no auth)
orch8-server --insecure

For production, set an API key via environment variable:

Production (with auth)
export ORCH8_API_KEY="your-secret-key"
orch8-server

The 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 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:latest
2

Define 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.

3

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.

4

Check the status

# Get instance state
curl http://localhost:8080/instances/<instance-id>

# See step outputs
curl http://localhost:8080/instances/<instance-id>/outputs
5

Control 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/sdk
import { 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-sdk
from 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-go
package 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)
}