Multi-Step Workflows
Multi-step workflows allow you to build complex verification logic that involves multiple API calls, polling for async job completion, and conditional branching.
When to Use Multi-Step
•Verifying async jobs that require polling until completion
•Making multiple dependent API calls (e.g., create → poll → validate)
•Extracting values from one response to use in subsequent requests
•Complex verification with conditional logic
Basic Structure
{
"verification_mode": "deterministic",
"verification": {
"type": "multi_step",
"workflow": {
"id": "async_job_verification",
"initial_variables": {
"job_id": "$.delivery.job_id",
"api_key": "$.delivery.api_key"
},
"steps": [
// Step definitions here
],
"timeout_ms": 60000,
"max_steps": 20
}
}
}Variable Binding
Variables extracted from delivery payload or previous steps can be referenced using {{variable_name}} syntax.
From Delivery Payload
$.delivery.field_name → {{field_name}}From Previous Step
{ "from_step": "step_id", "path": "$.response.value" }Step Types
http_requestMake an HTTP request and capture the response
{
"id": "fetch_status",
"name": "Fetch Job Status",
"type": "http_request",
"config": {
"url": "https://api.example.com/jobs/{{job_id}}",
"method": "GET",
"headers": {
"Authorization": "Bearer {{api_key}}"
},
"extract": {
"status": "$.data.status",
"result_url": "$.data.result_url"
}
}
}poll_untilRepeatedly poll an endpoint until a condition is met
{
"id": "wait_for_complete",
"name": "Wait for Job Completion",
"type": "poll_until",
"config": {
"url": "https://api.example.com/jobs/{{job_id}}",
"method": "GET",
"condition": {
"json_path": "$.status",
"operator": "equals",
"value": "complete"
},
"max_attempts": 10,
"interval_ms": 2000,
"extract_on_success": {
"$.result_url": "result_url"
}
}
}assertAssert that a condition is true
{
"id": "verify_result",
"name": "Verify Result Quality",
"type": "assert",
"config": {
"condition": {
"type": "comparison",
"left": { "from_step": "fetch_result", "path": "$.score" },
"operator": "gte",
"right": 0.8
}
}
}extract_variableExtract a value from a previous step output
{
"id": "get_download_url",
"name": "Extract Download URL",
"type": "extract_variable",
"config": {
"source": { "from_step": "fetch_status", "path": "$.data.download_url" },
"variable_name": "download_url"
}
}delayWait for a specified duration
{
"id": "wait",
"name": "Wait 5 seconds",
"type": "delay",
"config": {
"duration_ms": 5000
}
}Complete Example: Async Job Verification
This example shows a workflow that polls an async job until completion, then verifies the result.
{
"verification_mode": "deterministic",
"verification": {
"type": "multi_step",
"workflow": {
"id": "image_processing_job",
"initial_variables": {
"job_id": "$.delivery.job_id"
},
"steps": [
{
"id": "poll_completion",
"name": "Wait for Job Completion",
"type": "poll_until",
"config": {
"url": "https://api.example.com/jobs/{{job_id}}",
"method": "GET",
"condition": {
"json_path": "$.status",
"operator": "equals",
"value": "complete"
},
"max_attempts": 30,
"interval_ms": 2000,
"extract_on_success": {
"$.result.image_url": "output_url",
"$.result.quality_score": "quality"
}
}
},
{
"id": "verify_quality",
"name": "Verify Quality Score",
"type": "assert",
"config": {
"condition": {
"type": "comparison",
"left": { "from_step": "poll_completion", "path": "$.quality" },
"operator": "gte",
"right": 0.85
}
}
},
{
"id": "verify_output_exists",
"name": "Verify Output URL Accessible",
"type": "http_request",
"config": {
"url": "{{output_url}}",
"method": "HEAD",
"expected_status": 200
}
}
],
"timeout_ms": 120000,
"max_steps": 50
}
}
}Error Handling
When a step fails, the workflow stops and verification fails. Common failure scenarios:
TIMEOUTWorkflow exceeded timeout_ms or poll_until max_attempts reachedASSERTION_FAILEDAn assert step condition evaluated to falseHTTP_ERRORHTTP request returned unexpected status codeINVALID_RESPONSECould not parse response or extract required values