Direct Execution API for V2 Flows
If your integration calls a workflow directly through the API — rather than triggering it from the UI, an agent, or a schedule — use this reference to call V2 Flows correctly, including when migrating an existing V1 workflow.
Overview
V1 workflows execute through:
POST /actions/execute/direct
For a V2 Flow, use:
POST /tools/execute-workflow
The V2 endpoint is not a drop-in payload replacement. The V2 Flow ID is sent as tool_id, and Flow inputs are sent as plain runtime values under inputs.
Authentication
Provide your EKB API credentials as request headers:
X-API-KEY: <api-key>
X-API-SECRET: <api-secret>
Content-Type: application/json
Never include real credentials in documentation, source control, tickets, or chat messages. Revoke and regenerate any credential that has been exposed.
Request body
{
"project_id": "<project-id>",
"tool_id": "<v2-flow-id>",
"inputs": {
"<flow-input-name>": "<runtime-value>"
},
"execution_mode": "workflow",
"mode": "manual"
}
Input names are case-sensitive — use the input name configured in the V2 Flow. For example, an input named New Input 1 should be submitted as:
{
"inputs": {
"New Input 1": "I am Gaurav"
}
}
Do not send the Flow input's full definition as the runtime value:
{
"inputs": {
"New Input 1": {
"id": "new_input_1",
"type": "string",
"value": "I am Gaurav",
"required": true
}
}
}
The id, type, description, and required fields belong to the stored Flow configuration — the execution request should contain only the value.
Example
curl --location 'https://api.getodin.ai/tools/execute-workflow' \
--header 'X-API-KEY: <api-key>' \
--header 'X-API-SECRET: <api-secret>' \
--header 'Content-Type: application/json' \
--data '{
"project_id": "<project-id>",
"tool_id": "<v2-flow-id>",
"inputs": {
"New Input 1": "I am Gaurav"
},
"execution_mode": "workflow",
"mode": "manual"
}'
Executing the published version
Once the Flow has been published or promoted, add:
{
"environment": "live"
}
This selects the version deployed to the live environment. Omit environment during initial testing, before the Flow has been published.
The endpoint waits for the complete execution result by default. You can supply this explicitly when needed:
{
"return_response": true
}
Response
A successful request returns an execution result:
{
"success": true,
"message": "Workflow executed successfully",
"node_results": {},
"execution_time_ms": 1250,
"execution_id": "<execution-id>",
"error": null
}
The contents of node_results depend on the nodes used by the Flow.
Common errors
| Status | Meaning |
|---|---|
401 Unauthorized | The API key or secret is missing, invalid, or revoked |
402 Payment Required | The associated team doesn't have sufficient credits |
403 Forbidden | The API user isn't a project member or lacks permission to execute Flows |
404 Not Found | The tool_id doesn't exist or doesn't belong to the specified project |
422 Unprocessable Entity | A required request field is missing or has an invalid type |
200 with "success": false | The request was accepted, but a Flow node failed — inspect error, node_results, and execution_id |
When troubleshooting, record the HTTP status and full response body. Remove credentials and sensitive input data before sharing them.
Migrating from the V1 endpoint
| V1 | V2 |
|---|---|
Endpoint: /actions/execute/direct | Endpoint: /tools/execute-workflow |
flow_id | tool_id |
ui_form | inputs |
| Input definitions included | Not included — plain runtime values only, keyed by the configured Flow input name |
The endpoint /v2/actions/execute/direct is for legacy Automator/Activepieces execution and should not be used to execute migrated V2 Flows.
Migrate an existing V1 workflow to V2 using the in-platform migration tool.