Orchestrator
Build, trigger, and monitor multi-step AI workflows with 7 sub-resources — separate wfb_ API key required.
The Skytells Orchestrator is a workflow automation platform for building, triggering, and monitoring multi-step AI workflows. Access via client.orchestrator.
Orchestrator uses a separate wfb_… API key — it is not interchangeable with your Skytells platform key (sk-…). See Setup below.
Setup
You need both a Skytells platform key and an Orchestrator API key. If you only need Orchestrator (no Inference), you can omit the platform key.
The SDK uses a separate internal HTTP transport for Orchestrator:
- Sends
Authorization: Bearer wfb_…only - Never sends
x-api-keyto the Orchestrator host - Strips
x-api-keyfrom any shared headers
For client configuration details, see Client.
Setup
import Skytells from 'skytells';
const client = Skytells(process.env.SKYTELLS_API_KEY, {
orchestratorApiKey: process.env.ORCHESTRATOR_API_KEY, // wfb_…
});Sub-resources
client.orchestrator exposes 7 sub-resources:
| Sub-resource | Access | Purpose |
|---|---|---|
workflows | client.orchestrator.workflows | CRUD, code export, project download |
executions | client.orchestrator.executions | List, status, logs, bulk-delete |
webhooks | client.orchestrator.webhooks | Trigger workflows via HTTP POST |
integrations | client.orchestrator.integrations | Manage external integrations |
apiKeys | client.orchestrator.apiKeys | Manage Orchestrator API keys |
ai | client.orchestrator.ai | AI-powered workflow generation (streaming) |
user | client.orchestrator.user | Profile read and update |
Workflows
Full CRUD operations for workflows, plus code export and project download.
workflows.list()Promise<OrchestratorWorkflowSummary[]>
OrchestratorWorkflowSummary[].workflows.get(id)Promise<OrchestratorWorkflow>
OrchestratorWorkflow.workflows.create(payload)Promise<OrchestratorWorkflow>
OrchestratorWorkflow.workflows.update(id, payload)Promise<OrchestratorWorkflow>
OrchestratorWorkflow.workflows.delete(id)Promise<void>
workflows.duplicate(id)Promise<OrchestratorWorkflow>
OrchestratorWorkflow.workflows.getCode(id)Promise<string>
workflows.downloadProject(id)Promise<ArrayBuffer>
Workflows
const workflows = await client.orchestrator.workflows.list();
for (const wf of workflows) {
console.log(wf.id, wf.name);
}
const workflow = await client.orchestrator.workflows.get('workflow-id');Webhook Triggers
Trigger a workflow by sending a JSON payload. This is the primary way to invoke a workflow programmatically. The body can be any JSON object — it becomes the workflow's trigger input.
Webhook Triggers
const result = await client.orchestrator.webhooks.execute(
'workflow-id',
{
prompt: 'Generate a product image',
style: 'photorealistic',
background: 'white',
},
);
console.log(result.executionId);Executions
executions.list(workflowId)Promise<OrchestratorExecution[]>
executions.getStatus(executionId)Promise<OrchestratorExecutionStatus>
executions.getLogs(executionId)Promise<OrchestratorLogEntry[]>
executions.deleteAllForWorkflow(workflowId)Promise<void>
Executions
const executions = await client.orchestrator.executions.list('workflow-id');
for (const exec of executions) {
console.log(exec.id, exec.status);
}
const status = await client.orchestrator.executions.getStatus('execution-id');
console.log(status);Integrations
Manage external integrations (Slack, etc.) connected to the Orchestrator.
integrations.list(options?)Promise<OrchestratorIntegration[]>
{ type } filter.integrations.get(id)Promise<OrchestratorIntegration>
integrations.create(payload)Promise<OrchestratorIntegration>
integrations.update(id, payload)Promise<OrchestratorIntegration>
integrations.delete(id)Promise<void>
integrations.test(id)Promise<unknown>
Integrations
// List all, or filter by type
const all = await client.orchestrator.integrations.list();
const slack = await client.orchestrator.integrations.list({ type: 'slack' });
// Create
const integration = await client.orchestrator.integrations.create({
type: 'slack',
name: 'My Slack Integration',
config: { webhookUrl: 'https://hooks.slack.com/...' },
});
// Test
await client.orchestrator.integrations.test(integration.id);API Keys
Manage Orchestrator API keys (wfb_…).
The key value is returned only at creation time — store it securely immediately.
API Keys
const keys = await client.orchestrator.apiKeys.list();
const newKey = await client.orchestrator.apiKeys.create({
name: 'Production key',
});
// Store this immediately — returned only once
console.log(newKey.key); // "wfb_..."AI Workflow Generation
Generate a workflow using natural language. Returns an NDJSON stream of OrchestratorAiStreamOperation objects describing build steps as they're generated.
AI Generation
const stream = client.orchestrator.ai.generateWorkflow({
prompt: 'Create a workflow that generates product images from a product name',
});
for await (const operation of stream) {
console.log(operation);
// Each operation describes a build step
}User Profile
// Get profile
const user = await client.orchestrator.user.get();
// Update profile
await client.orchestrator.user.updateProfile({
name: 'New Name',
});Auth Scopes
| Route type | Auth |
|---|---|
Webhook trigger (POST /api/workflows/{id}/webhook) | Authorization: Bearer wfb_… |
| Management routes (list, create, update, delete) | May require session/cookie auth in some contexts |
If management routes return 401 with only a wfb_… key, use session authentication or the Orchestrator dashboard.
Error Handling
import { SkytellsError } from 'skytells';
try {
const workflows = await client.orchestrator.workflows.list();
} catch (e) {
if (e instanceof SkytellsError) {
if (e.errorId === 'SDK_ERROR') {
// orchestratorApiKey was not provided
console.error('Set orchestratorApiKey in ClientOptions');
} else if (e.httpStatus === 401) {
// Invalid or expired wfb_… key
console.error('Invalid Orchestrator API key');
} else {
console.error(e.errorId, e.httpStatus, e.message);
}
}
}For the full error reference, see Errors.
Best Practices
- Store
wfb_…keys in environment variables — never in source code. - Use
apiKeys.create()to generate per-environment keys (staging vs production). - Use
executions.getStatus()to poll long-running workflows instead of holding connections open. - Validate trigger input schemas before calling
webhooks.execute(). - Clean up old executions via
executions.deleteAllForWorkflow()to keep dashboards manageable.
Related
- Orchestrator Product — Platform overview, dashboard, and concepts
- Orchestrator API Keys — Managing
wfb_keys - Predictions — Run individual model predictions (Inference API)
- Models — Discover models available in workflows
- Webhooks — Inbound webhook verification for prediction callbacks
- Errors — All error IDs and handling patterns
- Client — Dual-key setup (
sk-+wfb_) and client configuration
How is this guide?