Test a Workflow over scripted events
POST /v1/workflows/{workflow_id}/test
| Property | Value |
|---|---|
| Operation | test_workflow |
| Group | Workflows |
| Scope | workflows:write |
| Route class | control |
| Idempotency | Idempotency-Key accepted: a retry with the same key replays the first answer |
| Audit | Not audited: A dry run: it changes no state and reads no Call content, so it writes no Audit event (ADR 0012, workflows-and-processes.md section 9.8). |
| Released in | 1.59.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
Compiles the draft, or a published version, and runs the interpreter over it (1.59.0): the start, then each scripted event (a node's completion with its outlet and output, a node's failure, a closed Turn or the Call's end), with each node a step evaluates evaluated by the engine. It answers each step's evaluations, value, effects, records and state hook dispatches, the nodes entered, the node it waits on and how the Call would end. A draft that does not compile is refused as a publish would be. It writes nothing: no Call, Call event, Audit event or Usage event.
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the workflows:write scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl -X POST "$VOCAL_API/v1/workflows/wfl_.../test" \
-H "Authorization: Bearer $VOCAL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"events": []
}'const response = await fetch(`${process.env.VOCAL_API}/v1/workflows/wfl_.../test`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"events": []
}),
});
console.log(response.status, await response.text());import os
import uuid
import requests
response = requests.post(
f"{os.environ['VOCAL_API']}/v1/workflows/wfl_.../test",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"events": [],
},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workflow_id | path | WorkflowId | yes | The id of a Workflow: wfl_ and the row's UUIDv7 in 26 Crockford base32 characters. Opaque and safe to log. |
idempotency-key | header | string | no | A client-chosen key, kept 24 hours per Organization, environment and route. A replay returns the stored response. |
Request body
Content type application/json, required: WorkflowTestRequest.
| Field | Type | Required | Description |
|---|---|---|---|
context | WorkflowTestContextInput | no | |
events | array of WorkflowTestEventInput | yes | The scripted events after the start, in order; empty to see the start alone. |
slots | map of any | no | Slot values at the start, over the declared defaults. |
version | WorkflowTestVersion | no |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
200 | application/json | WorkflowTestResult | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden |
404 | application/json | ErrorEnvelope | not_found |
409 | application/json | ErrorEnvelope | idempotency_in_progress, idempotency_key_reused |
422 | application/json | ErrorEnvelope | validation_failed, capability_not_available |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
Fields of the 200 answer
The shape is WorkflowTestResult.
| Field | Type | Required | Description |
|---|---|---|---|
ended_reason | EndedReason or null | yes | How the Call would end: workflow_complete once a hangup or end node was entered, the reason of a scripted session.ended, or null while it runs. |
final | MachineState | yes | |
object | "workflow_test" | yes | |
outputs | object or null | no | The Workflow's declared outputs (1.60.0): the outputs expressions of the hangup or end node the run entered, evaluated over its value; null while it runs or when that node declares none. Content of the scripted values. Absent from an api before 1.60.0. |
path | array of MachineId | yes | Every node the run entered or evaluated, in order. |
steps | array of WorkflowTestStep | yes | The start, then one step per scripted event. |
version | integer or null | yes | The version run; null for the draft. |
waiting_on | MachineId or null | yes | The node whose completion the run waits for after the last event; null when it ended. |
workflow_id | WorkflowId | yes |