By Trigger ID#
Use when the workflow has a trigger (HTTP, webhook, job, etc.). The triggerId is the trigger's ID. For workflows pushed via SDK's stepsToNodes, the default trigger ID is trigger. For workflows created in the UI, get the trigger ID from the workflow group (e.g. trigger-webhook-1234567890).
import { FlosyncClient } from 'cliodot';
const client = new FlosyncClient({
baseUrl: 'https://your-api-domain.com',
apiKey: process.env.FLOSYNC_API_KEY,
apiSecret: process.env.FLOSYNC_API_SECRET
});
await client.authenticate();
const result = await client.workflows.run('workflow-group-id', 'trigger', {
payload: { name: 'John', email: 'john@example.com' }
});
console.log(result);
Payload: { payload?: any; environment?: "dev" | "prod" } – The payload is passed as trigger.data in the workflow. Use environment: "prod" to run the promoted production workflow (prod vars/secrets, logs stored). Default is "dev".
Return value: The SDK returns only the final result (responder body or last step output). Step results are stripped.
By Webhook Path#
Use when the workflow is exposed via HTTP and you know the webhook path. The API searches for a workflow matching the path and method.
const result = await client.workflows.runByWebhook('/orders', 'POST', {
body: { items: [{ id: '1', qty: 2 }], customerId: 'cust-123' }
});
Parameters:
webhookPath– e.g./orders,/api/v1/usersmethod–GET,POST,PUT,PATCH,DELETEpayload–{ body?: any; environment?: "dev" | "prod" }– The body is passed astrigger.data. Useenvironment: "prod"to run the promoted production workflow.
Return value: Same as run() – final result only.
Dev vs Prod#
When running workflows via run() or runByWebhook():
| Environment | Workflow source | Vars/secrets | Logs |
|---|---|---|---|
dev (default) |
Dev table (unpromoted) | Project dev vars/secrets | Not stored |
prod |
Prod table (promoted only) | Project prod vars/secrets | Stored |
Pass environment: "prod" in the payload to run the promoted workflow. The workflow must be promoted first via client.workflows.promote(groupId).
API: Use query ?environment=prod, header X-Environment: prod, or body { environment: "prod" }.
Via SDK#
import { FlosyncClient, flosync, v } from 'cliodot';
const client = new FlosyncClient({
baseUrl: process.env.FLOSYNC_BASE_URL,
apiKey: process.env.FLOSYNC_API_KEY,
apiSecret: process.env.FLOSYNC_API_SECRET
});
await client.authenticate();
const w = flosync
.workflow('order-processor')
.http('POST', '/orders')
.step('save', s => s.db('mongodb', 'insertOne', { collection: 'orders', document: v.body() }))
.step('respond', s => s.responder('json', { body: v.stepResult('save') }))
.build();
await client.workflows.push(w);
push() creates the workflow if it does not exist, or updates it if it exists (by workflow._id).
IWorkflow Structure#
For programmatic creation without WorkflowBuilder:
interface IWorkflow {
_id: string;
name: string;
description?: string;
status?: string;
trigger: { type: string; cron?: string; timezone?: string; ... };
steps: IWorkflowStep[];
vars?: Record<string, any>;
project_id?: string;
}
The SDK's stepsToNodes transformer converts IWorkflow (steps) to the server's node/edge format before push.
List and Filter#
const { workflowGroups, pagination } = await client.workflows.list({
status: 'active',
type: 'webhook',
name: 'order',
project_id: 'proj-123',
page: 1,
limit: 20
});
Promote to Production#
Promote a dev workflow to production (clones to prod, API execution loads from prod):
await client.workflows.promote('workflow-group-id');
Pull Workflow#
Fetch a workflow from the server as IWorkflow (steps format):
const workflow = await client.workflows.pull('workflow-group-id');
Full Example#
import { FlosyncClient, flosync, v } from 'cliodot';
async function main() {
const client = new FlosyncClient({
baseUrl: process.env.FLOSYNC_BASE_URL || 'http://localhost:8080',
apiKey: process.env.FLOSYNC_API_KEY,
apiSecret: process.env.FLOSYNC_API_SECRET
});
await client.authenticate();
const w = flosync
.workflow('greet-api')
.http('POST', '/greet')
.step('validate', s =>
s.validator({ name: v.body('name') }).then('greet').else('error')
)
.step('greet', s =>
s.transform({
message: v.expr('"Hello, " + body.name + "!"'),
timestamp: v.expr('new Date().toISOString()')
})
)
.step('respond', s =>
s.responder('json', { body: v.stepResult('greet') })
)
.step('error', s =>
s.responder('json', { statusCode: 400, body: { error: 'name required' } })
)
.build();
await client.workflows.push(w);
const result = await client.workflows.run('greet-api', 'trigger', {
payload: { name: 'World' }
});
console.log(result);
}
main();