Logs
Run-log stats, export, and execution detail via the v1 API.
Observability for workflow runs under /api/v1/logs/* (not audit logs). Any valid bearer API key. Missing token → 401 { "error": "Valid bearer API key is required" }. Always scoped to the key workspace.
There is no GET /api/v1/logs list. Session GET /api/logs returns { runs[] } with the same filters. No Idempotency-Key (reads only).
Endpoints
| Method | Path | Response |
|---|---|---|
| GET | /api/v1/logs/stats | JSON { workspaceId, filters, generatedAt, stats } |
| GET | /api/v1/logs/export | JSON or CSV attachment |
| GET | /api/v1/logs/executions/{executionId} | Execution details object (unwrapped) |
Shared query filters
Used by stats and export. Empty or all → no filter (null in the echoed filters object).
| Param | Notes |
|---|---|
status | Run status |
trigger | manual | webhook | schedule | copilot | api | email | rss |
workflowId | Exact workflow |
level | Keep runs that have a log at this level (applied after fetch) |
dateFrom / dateTo | Durable store filters queuedAt; in-memory store uses startedAt |
query | Case-insensitive text over run id, names, status, trigger, error, input/output, steps, logs |
sort | newest (default) | oldest | duration | cost | workflow | status |
limit | Route default 200 if omitted or non-numeric. listRuns then clamps 1–200 |
Durable listing fetches at most 200 rows from Prisma (take: 200) before level / query / sort / limit slice. There is no offset/cursor.
Stats
GET /api/v1/logs/stats → stats from buildRunLogDashboard: totalRuns, failedRuns, succeededRuns, averageDurationMs, totalCostCredits, successRate (0–100), activeRuns (queued | running | waiting), p95DurationMs, statusBreakdown[], triggerBreakdown[], slowestRuns (top 5), recentFailures (top 5). Echoed filters includes workspaceId and limit.
Export
GET /api/v1/logs/export?format=json|csv (format other than csv → JSON). Headers: Content-Disposition: attachment; filename="fluxus-logs-{workspaceId}-{YYYY-MM-DD}.{json|csv}", Cache-Control: no-store.
JSON body: { workspaceId, exportedAt, filters, runCount, runs[] } (filters uses "all" / "" defaults rather than null). CSV columns: run_id, workspace_id, workflow_id, workflow_name, status, trigger, started_at, finished_at, duration_ms, credits, step_count, log_count, error.
Execution details
GET /api/v1/logs/executions/{executionId} — executionId is the run id. Wrong workspace or missing → 404 { "error": "Execution not found" }.
Body: executionId, workflowId, workflowState (node/edge snapshot), executionMetadata, relatedRuns (parentRun?, childRuns[] with executionUrl /api/v1/logs/executions/{id}), nodeRunStates, timeline[] (type run | step | log), run.
Run execute/status responses also link here as execution.
Known gaps
- No v1 run-list twin of
GET /api/logs(use Runs or export). - Limit is not a stable page; Prisma
take: 200can hide older matches beforequery/level. - Export filename prefix is
fluxus-logs-. - Not audit events (
GET /api/v1/audit-logs).
