test-run-cloudflow-flow
dci test-run-cloudflow-flow <flowId> [body] [flags]
Runs a flow once as a test, and accepts an unpublished (draft) flow — unlike
actions/trigger, which requires the flow to be published. Use this to verify a newly
authored or edited flow before publishing it.
Execution is identical to a production run: the same graph, the same bound connections, the same credentials, and the same approval behaviour. An approval-gated node still parks the run and its side effect still waits for a real approval — there is no request that skips one.
The run is recorded as a test, so it does not appear in run history, does not count
towards dashboard statistics, does not become a dashboard widget's data source, and does
not consume a scheduled-run budget. It does hold the flow's concurrency lock, so a 409
is returned while the flow is already running.
The flow's first node must be a webhook, scheduled, or manual trigger.
Before dispatching, the flow is validated with the same checks publish applies — a draft
has never been through them. A flow that fails returns 422 listing every offending node
at once, so all of them can be fixed in one pass.
Poll the Location URL to follow the run and read what each node produced.
Pass ?dryRun=true to validate the flow without starting a run.
flowId— The ID of the flow to test-run.
Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.
--dry-run here is the API's own dry run — the request is sent and the server-side flow
validator answers; nothing starts. The CLI generates a throwaway idempotency key for dry runs;
pass your own --idempotency-key for real runs.
A run can start even when the response fails (for example a 5xx). Before minting a new key,
check dci list-cloudflow-flow-runs <flow-id> --mode test — re-sending with the same key
is always safe and never starts a second run. Test runs execute nodes for real (approval steps
are never bypassed) but are excluded from run history, statistics, and schedule budgets, and
they hold the flow's concurrency lock (409 while the flow is already running).
Examples
# Validate a draft with the same checks publishing applies, without starting a run.
dci test-run-cloudflow-flow <flow-id> --dry-run
`valid: true`, or a 422 whose `details[]` names every invalid node (`nodeId` and message) so they can all be fixed in one pass.
# Start one test run; the idempotency key guarantees a retry can never start a second run.
dci test-run-cloudflow-flow <flow-id> --idempotency-key "$(uuidgen)"
A 202 snapshot of the run taken at dispatch: `id`, `status: pending`, `isTest: true`. Follow it with `dci get-cloudflow-flow-run <flow-id> <run-id>`.
# Capture the run ID for a polling loop.
dci test-run-cloudflow-flow <flow-id> --idempotency-key "$(uuidgen)" --output json | jq -r .id
Request
Content-Type: application/json
Raw JSON schema
{
"type": "object",
"description": "Optional JSON payload forwarded to the trigger node, so a webhook-triggered flow\ncan be test-run with sample input. Omit or send `{}` for flows that need no input."
}
Flags
| Flag | Type | Default | Example | Description |
|---|---|---|---|---|
--dry-run | boolean | Validate the flow and return the outcome without starting a run. |
Every command also accepts the CLI-wide flags for output shaping — see Output formats and Table output options.
Output
Dry-run only. The flow was validated and no run was created.
By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.
| Field | Type | Description |
|---|---|---|
valid | boolean | True when the flow passed every check and is runnable. |
details | array of object | One entry per node that must be fixed. Present only when valid is false. |
details[].nodeId | string | |
details[].message | string | |
type | string | |
title | string | |
status | integer | |
detail | string | |
code | string | |
retryable | boolean |
Raw JSON schema
{
"type": "object",
"description": "Validation outcome for a test run. Returned on `200` for `?dryRun=true`, and on `422` —\nwith the problem fields populated — when a flow cannot be run.",
"required": [
"valid"
],
"properties": {
"valid": {
"type": "boolean",
"description": "True when the flow passed every check and is runnable."
},
"details": {
"type": "array",
"description": "One entry per node that must be fixed. Present only when `valid` is false.",
"items": {
"type": "object",
"required": [
"nodeId",
"message"
],
"properties": {
"nodeId": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
},
"type": {
"type": "string"
},
"title": {
"type": "string"
},
"status": {
"type": "integer"
},
"detail": {
"type": "string"
},
"code": {
"type": "string"
},
"retryable": {
"type": "boolean"
}
}
}
Errors
On failure, dci prints a single error message — with a hint when one is available — and exits with a typed code your scripts can branch on. See Errors and exit codes for the full contract.
HTTP status to exit code mapping
| HTTP status | Exit code | Error code | Meaning |
|---|---|---|---|
| 400, 422 | 30 | VALIDATION_ERROR | The arguments or request body were rejected. Review the command's flags and payload. |
| 401 | 10 | AUTHENTICATION_FAILED | Not signed in, or the API token is invalid. Run dci login or check DCI_API_KEY. |
| 403 | 11 | PERMISSION_DENIED | The DoiT user or the active customer context does not have access. |
| 404 | 20 | RESOURCE_NOT_FOUND | The requested resource does not exist. Check the identifier argument. |
| 409 | 21 | RESOURCE_CONFLICT | The operation conflicts with the resource's current state. |
| 429 | 50 | RATE_LIMITED | Too many requests. Retryable — the CLI reports the server-provided delay. |
| 500 | 40 | API_SERVER_ERROR | The API failed to process the request. Retryable; contact DoiT support if it persists. |
Related
- get-cloudflow-flow-run — Read a flow run, node by node
- list-cloudflow-flow-runs — List a flow's runs
- import-cloudflow-flow — Import a flow bundle
- export-cloudflow-flow — Export a flow as a portable bundle
- trigger-cloudflow-webhook — Trigger a webhook flow
- API reference: POST /cloudflow/v1/flows/{flowId}/actions/test-run
Aliases: testruncloudflowflow