Runs & debugging
Every call to /v1/evaluate/{slug} creates a run — a durable record of execution you can inspect in the console or query from the tenant API.
Run statuses
| Status | Meaning |
|---|---|
| running | Actively executing nodes |
| waiting | Paused at a wait_for_event node |
| completed | Reached end with a response |
| failed | Unhandled error or validation failure |
| timedOut | Hit the wait deadline without a reply |
The Runs dashboard
Console → Runs opens a live dashboard:
- KPI tiles — total runs, success rate, p95 latency, currently-waiting count
- Stacked time-series — runs per bucket, broken down by status. Click any bar to drill into that bucket
- Top flows — busiest 10 flows by volume, sortable by failure count. Click a flow to scope the rest of the page
- Latency chart — p50 / p95 / p99 across the selected range
- Filterable table — search by run id or correlation key, filter by status, paginate cursor-style. Each row shows the targeted version (
v#), the provenance source (cli/console/cli·draft/console·draft) as a badge, and the short git commit when the version was published via CLI. Avia cli | console | allfilter pill row sits next to the status chips so you can answer "did the last CI deploy break anything?" in one click. The same filter is available on the API asGET /v1/runs?source=cli|designer.
Time range presets: 1h · 24h · 7d · 30d · 90d plus drilled-in custom ranges. The system picks the bucket size automatically (minute / hour / day) so the chart always renders 24–90 points.
Live presets (1h, 24h) auto-refresh every 30 seconds. Toggle in the top right.
Inspecting a single run
Click any row to open the detail page:
- Timeline — nodes executed in order, with per-step duration and output JSON
- Output — final response or pause metadata
- Per-step detail — HTTP status codes, expression results, errors
- Send reply (waiting runs only) — simulate the resume event without curl
Use this to answer questions like "Why was this user denied?" or "Which API call failed?"
Paused runs
When a flow hits wait_for_event:
- Evaluate returns a response including the run id and pause info
- Your UI shows a form or redirect (
uiActionon the node) - When the user completes, call resume:
curl -X POST "https://api.fetchcatch.com/v1/runs/{runId}/resume" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event": "user_confirmed",
"payload": { "confirmed": true }
}'
The event string must match the node's eventName.
Correlation keys
Pass correlationKey in evaluate requests to tie runs to your own request IDs:
{
"correlationKey": "order-9821",
"userId": "u-123"
}
The dashboard search box matches on correlation keys, so you can paste an order ID from your app logs and jump straight to the run.
API — querying runs programmatically
All of the following are available on both policies:
- Console JWT (
Authorization: Bearer <jwt>) - Tenant API key (
X-FetchCatch-Key: <key>)
| Method | Path | Purpose |
|---|---|---|
GET |
/v1/runs |
List runs in the workspace. Filters: flowId, status, fromUtc, toUtc, search, cursor, take (max 200) |
GET |
/v1/runs/{id} |
Detail + step trace |
GET |
/v1/runs/stats?fromUtc=&toUtc= |
KPIs, time-series, top flows, p50/p95/p99 |
POST |
/v1/runs/{id}/resume |
Resume a waiting run (tenant API) |
Stats response shape:
{
"fromUtc": "2026-05-24T12:00:00Z",
"toUtc": "2026-05-25T12:00:00Z",
"bucket": "1h",
"total": 1247,
"completed": 1203,
"failed": 41,
"timedOut": 3,
"running": 0,
"waiting": 0,
"waitingNow": 2,
"successRate": 0.9648,
"p50Ms": 124,
"p95Ms": 280,
"p99Ms": 612,
"series": [
{ "bucketStartUtc": "...", "completed": 50, "failed": 1, "timedOut": 0, "waiting": 0, "running": 0, "p50Ms": 120, "p95Ms": 290, "p99Ms": 510 }
],
"topFlows": [
{ "flowId": "...", "flowSlug": "checkout", "flowName": "Checkout", "total": 812, "failed": 4 }
],
"truncated": false
}
truncated: true means the range exceeded 100k completed runs and percentiles are approximate. Narrow the range to get exact numbers.
Pagination
The list endpoint returns at most take items (default 50, max 200) and a nextCursor opaque token. Pass it as ?cursor=... to get the next page; the cursor encodes (StartedAtUtc, Id) to provide stable ordering even when new runs are inserted.
Common failure modes
| Error | Likely cause |
|---|---|
| Input validation failed | Missing required field in start inputSchema |
| HTTP node error | Upstream 4xx/5xx; check auth profile |
| Expression error | Invalid JSONata; test in designer |
| Response validation failed | Decision didn't set required response type fields |
| Event mismatch on resume | Wrong event name |
Retention
Runs are stored in SQL indefinitely today. The dashboard's stats endpoint caps in-memory percentile computation at 100,000 completed runs per request — beyond that it returns truncated: true and you should narrow the range. For high-traffic workspaces this means plan retention before going to production scale. A configurable retention worker is on the roadmap; until then, manual deletes from FlowRuns are safe (FlowRunSteps cascade).