Run Workflows
Execute any workflow as a headless API by passing just the input values — no need to send the full node graph.
The Run endpoint lets you execute any workflow you own by passing only the input values. The server loads the saved workflow, injects your inputs, and executes the full pipeline. This is how you turn visual workflows into programmable APIs.
Describe Inputs
GET /api/v1/workflows/{id}/run
Returns the input schema for a workflow so you know what to pass.
Request
curl https://www.wireflow.ai/api/v1/workflows/YOUR_WORKFLOW_ID/run \
-H "Authorization: Bearer sk-your-api-key"
Response 200 OK
{
"data": {
"workflowId": "cm1abc123",
"workflowName": "Video Analyzer",
"inputs": [
{
"nodeId": "node-tiktok",
"label": "TikTok Import",
"type": "url",
"required": true,
"description": "TikTok video URL"
},
{
"nodeId": "node-theme",
"label": "Analysis Theme",
"type": "text",
"required": false,
"default": "Break down the visual storytelling techniques"
}
],
"endpoint": "/api/v1/workflows/cm1abc123/run",
"method": "POST",
"example": {
"inputs": {
"node-tiktok": "<url>",
"node-theme": "Break down the visual storytelling techniques"
}
}
}
}
Input Types
type tells you what the input FEEDS, not which node holds it. It comes
from the declared type of the port the input is wired into. Wireflow's Image
Input node is the universal importer — it carries sound and video just as
happily — so the node it lives on is not evidence of what the value is for. When
an input is wired to nothing, type falls back to the node's own kind.
| Type | Description | Wired to |
|---|---|---|
text |
Free-form text input | TEXT ports; unwired Text Input / Prompt nodes |
image |
HTTPS image URL | IMAGE ports; unwired Image Input / Media Upload |
audio |
HTTPS audio URL | AUDIO ports, e.g. a render node's audio_2 |
video |
HTTPS video URL | VIDEO ports |
url |
Any media URL | ports of conflicting media kinds; unwired import nodes |
number |
Numeric value | Number, Seed nodes |
boolean |
True/false toggle | Toggle nodes |
select |
Choice from options | List Selector nodes |
So four sound effects imported through Image Input nodes and wired into a render
node's audio_2 / audio_3 / audio_4 ports report audio. When consumers
disagree on the media kind, type is url and description names the conflict.
required: false means the input already resolves without you — it holds a
value (see default) or every port it feeds declares itself optional. A port
that declares no required at all counts as unknown, never optional, so
required: true can be conservative.
Back-compat.
audioandvideoare recent additions to this union. If you switch ontype, add cases for them: an input that used to reportimageorurlmay now reportaudioorvideo. This is advertisement only — it does not change how a run injects your value, what it costs, or which values are refused.
How Inputs Are Detected
- If the workflow has published input settings (
exposedInputs), only those nodes are exposed - Otherwise, all input-category nodes and utility import nodes without incoming connections are automatically exposed
Run a Workflow
POST /api/v1/workflows/{id}/run
Executes the workflow with your input values. Returns 202 with an execution ID for polling.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
inputs |
object |
No | Map of nodeId → value. Omit to run with saved defaults. |
Request
curl -X POST https://www.wireflow.ai/api/v1/workflows/cm1abc123/run \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"inputs": {
"node-tiktok": "https://www.tiktok.com/t/ZP8bar3Dk/"
}
}'
Response 202 Accepted
{
"data": {
"executionId": "exec_789",
"status": "running",
"poll": "/api/v1/workflows/executions/exec_789/poll"
}
}
The Location header also points to the poll URL.
Poll for results using the Poll endpoint:
curl https://www.wireflow.ai/api/v1/workflows/executions/exec_789/poll \
-H "Authorization: Bearer sk-your-api-key"
Complete Example
Build a workflow in the editor, then call it from code:
const WIREFLOW_API = 'https://www.wireflow.ai/api/v1';
const API_KEY = process.env.WIREFLOW_API_KEY;
// 1. Discover the inputs
const schema = await fetch(`${WIREFLOW_API}/workflows/${workflowId}/run`, {
headers: { Authorization: `Bearer ${API_KEY}` },
}).then((r) => r.json());
console.log('Available inputs:', schema.data.inputs);
// 2. Run the workflow
const { data } = await fetch(`${WIREFLOW_API}/workflows/${workflowId}/run`, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputs: {
'node-tiktok': 'https://www.tiktok.com/t/ZP8bar3Dk/',
},
}),
}).then((r) => r.json());
// 3. Poll until complete
let result;
while (true) {
const poll = await fetch(`${WIREFLOW_API}${data.poll}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
}).then((r) => r.json());
if (poll.status === 'COMPLETED') {
result = poll;
break;
}
if (poll.status === 'FAILED') throw new Error(poll.error);
await new Promise((r) => setTimeout(r, 2000));
}
console.log('Results:', result.nodeResults);
Credits
The API key owner's credits are charged for each AI model node that runs. Text input and utility nodes are free. Use the credit pre-check error to handle insufficient balance gracefully.
Comparison with Execute
/run |
/execute |
|
|---|---|---|
| Input | Just the values you want to override | Full nodes + edges arrays |
| Workflow source | Loaded from saved state | Sent in request body |
| Best for | Programmatic use, integrations, automation | Editor (frontend sends live canvas state) |
| Auth | API key or session | API key, session, or internal |