---
title: "Retrieve a workflow run"
method: GET
path: "/api/v3/workflows/runs/{runId}"
tags: ["V3 Workflows"]
---

# Retrieve a workflow run

`GET /api/v3/workflows/runs/{runId}`

Returns one workflow run by globally unique run id, including the full debug payload: the
captured `triggerPayload`, the run `data` (per-step results), the persisted `logs` trace,
and retry metadata (`attempt`, `nextAttemptAt`, `lastErrorAt`). Scope 1 deliberately exposes
these as JSON dumps so users and agents can understand exactly what happened in a run.

Poll this endpoint after `POST /api/v3/workflows/{workflowId}/test`: runs execute
asynchronously and transition `queued` → `running` → `completed`/`failed`/`canceled`.

Unknown or inaccessible run ids return `403` rather than `404` to avoid leaking
cross-workspace resource existence.

## Path parameters

- `runId` string, cuid2, required

## Response `200`

Workflow run retrieved successfully

- object
  - `data` WorkflowRunResource, required — Slim run shape embedded as `lastRun` in workflow resources. The runs list (`GET /api/v3/workflows/runs`) returns `WorkflowRunListItem`, which extends this with `workflowName`. Excludes `triggerPayload`, `data`, and `logs`.
    - `id` string, cuid2, required
    - `workflowId` string, cuid2, required
    - `workspaceId` string, cuid2, required
    - `workflowVersionId` string, cuid2, nullable, required — Immutable workflow version snapshot the run executes against. `null` for dry runs of workflows that have never been enabled. Version contents are not readable through the v3 API in Scope 1.
    - `status` 'queued' | 'running' | 'completed' | 'failed' | 'canceled', required — Workflow run lifecycle state. `completed`, `failed`, and `canceled` are terminal. Valid transitions: `queued` → `running`, `running` → `queued` (retry/backoff), `queued` → `canceled`, and `running` → `completed`/`failed`/`canceled`. Retries do not introduce a separate status; retry state is exposed via `attempt` and `nextAttemptAt`.
    - `isDryRun` boolean, required — `true` for runs created by `POST /api/v3/workflows/{workflowId}/test`.
    - `triggerType` 'response.completed', required
    - `surveyId` string, cuid2, nullable, required
    - `responseId` string, cuid2, nullable, required — Survey response that triggered the run. `null` for synthesized dry-run data or when the response was deleted.
    - `error` string, nullable, required — Terminal or most recent failure reason. `null` while the run is healthy.
    - `attempt` integer, required — Retry attempt counter. `0` on the first execution; retries increment it without changing `status`.
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `startedAt` string, date-time, nullable, required
    - `finishedAt` string, date-time, nullable, required
    - `triggerPayload` WorkflowTriggerPayload, required — Trigger payload snapshot captured when a run is created, mirroring `ZWorkflowTriggerRunPayload`. Additional runner keys may be present.
      - `type` 'response.completed', required
      - `workspaceId` string, cuid2, required
      - `surveyId` string, cuid2, required
      - `responseId` string, cuid2, required — For dry runs without a `responseId` input, this references the synthesized sample response.
      - `endingCardId` string, cuid2 — Ending card the respondent reached, when the survey uses ending cards.
      - `data` object — Response data snapshot used by the runner.
      - `triggeredAt` string, date-time, required
    - `data` WorkflowRunData, required — Run execution data persisted with the run, mirroring `ZWorkflowRunData`. Scope 1 exposes this as a debug-oriented JSON dump. Additional runner keys may be present.
      - `trigger` WorkflowTriggerPayload — Trigger payload snapshot captured when a run is created, mirroring `ZWorkflowTriggerRunPayload`. Additional runner keys may be present.
        - `type` 'response.completed', required
        - `workspaceId` string, cuid2, required
        - `surveyId` string, cuid2, required
        - `responseId` string, cuid2, required — For dry runs without a `responseId` input, this references the synthesized sample response.
        - `endingCardId` string, cuid2 — Ending card the respondent reached, when the survey uses ending cards.
        - `data` object — Response data snapshot used by the runner.
        - `triggeredAt` string, date-time, required
      - `steps` WorkflowRunStepResult[], required
        - `stepId` string, required — Node id of the executed step.
        - `stepType` string, required — Node/step type, e.g. `response.completed` or `send_email`.
        - `status` 'pending' | 'running' | 'succeeded' | 'failed' | 'skipped', required — Status of one executed (or skipped) workflow step within a run.
        - `input` object — Step input snapshot.
        - `output` object — Step output snapshot, or the mocked output for dry runs.
        - `error` string
        - `startedAt` string, date-time
        - `finishedAt` string, date-time
    - `logs` WorkflowRunLog[], required — Persisted step-by-step trace, ordered by `sequence`. Empty while the run is still `queued`.
      - `id` string, cuid2, required
      - `runId` string, cuid2, required
      - `sequence` integer, required — Order of the entry within the run.
      - `stepId` string, required
      - `stepType` string, required
      - `status` 'pending' | 'running' | 'succeeded' | 'failed' | 'skipped', required — Status of one executed (or skipped) workflow step within a run.
      - `input` object, required — Step input snapshot. Empty object when nothing was recorded.
      - `output` object, required — Step output snapshot (mocked for dry runs). Empty object when nothing was recorded.
      - `error` string, nullable, required
      - `startedAt` string, date-time, nullable, required
      - `finishedAt` string, date-time, nullable, required
    - `idempotencyKey` string, nullable, required — Deduplication key for this run, unique per workflow. Set from the `Idempotency-Key` header on dry runs or from trigger-event deduplication.
    - `nextAttemptAt` string, date-time, nullable, required — When the next retry attempt is scheduled. `null` when no retry is pending.
    - `lastErrorAt` string, date-time, nullable, required

## Other responses

- `400` — Bad Request — malformed JSON, invalid query/body/params, duplicate name, or unsupported field.
- `401` — Not authenticated (no valid session or API key).
- `403` — Forbidden — no workspace access, or resource does not exist (404 not used; avoids existence leak).
- `429` — Rate limit exceeded.
- `500` — Internal Server Error.

## Changes

> 21 revisions in range; 1 could not be searched.

- **2026-08-04** `aa2a946d376d` — 5 warning
  - added the new `service_unavailable` enum value to the `code` response property for the response status `400`
  - added the new `service_unavailable` enum value to the `code` response property for the response status `401`
  - added the new `service_unavailable` enum value to the `code` response property for the response status `403`
  - added the new `service_unavailable` enum value to the `code` response property for the response status `429`
  - …1 more
- **2026-07-31** `252a618df054` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/formbricks/apis/formbricks-api-v3/changes/api/v3/workflows/runs/:runId/get.md)

---

[API](https://skmtc.dev/formbricks/apis/formbricks-api-v3.md) · [All operations](https://skmtc.dev/formbricks/apis/formbricks-api-v3/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/formbricks/formbricks-api-v3/revisions/3c2c022e49d2/schema)
