---
title: "List workflow executions"
method: GET
path: "/v1/workflow-executions"
tags: ["Workflows"]
---

# List workflow executions

`GET /v1/workflow-executions`

## Request

- Base URL: `https://api.getfinero.com/functions/v1/api`
- URL: `https://api.getfinero.com/functions/v1/api/v1/workflow-executions`
- Auth: HTTP bearer

Audit trail of Payment Link Automation runs (what ran, what was skipped, why), with stable reason codes; `GET /v1/workflows` explains each. Holds each workspace's newest five hundred runs (a few more for a moment when runs are written at once); older ones are removed as new ones are written. Email workflows record nothing here: an absent execution never means an email was not sent. Payment Arrangement tasks are listed by `GET /v1/tasks`. Cursor-paginated: pass `limit` (1–100) and send pagination.next_cursor back as `cursor` until has_more is false. To learn HOW MANY rows match without walking every page, pass `include_total=true` once and read pagination.total_count.

Available to **admin and readonly** API keys (no side effects).

## Query parameters

- `limit` integer
- `cursor` string
- `order` 'asc' | 'desc'
- `include_total` boolean
- `workflow_type` 'payment_link_automation' | 'payment_arrangement' | 'email_notification' | 'internal_notification'
- `status` 'pending' | 'processing' | 'succeeded' | 'skipped' | 'failed'
- `invoice_id` string, uuid

## Response `200`

Success

- object
  - `data` object[], required: Workflow executions, newest first by creation time.
    - `id` string, uuid, required: Workflow execution id.
    - `workflow_type` 'payment_link_automation' | 'payment_arrangement' | 'email_notification' | 'internal_notification', required: Which automation ran.
    - `invoice_id` string, uuid, nullable, required: Related invoice.
    - `installment_id` string, uuid, nullable, required: Related installment.
    - `payment_link_id` string, uuid, nullable, required: Related payment link.
    - `trigger_reason` string, required: What triggered the run.
    - `status` 'pending' | 'processing' | 'succeeded' | 'skipped' | 'failed', required: Outcome of this execution.
    - `reason_code` string, nullable, required: Categorical reason for a skip/failure (stable machine-readable code). the workflows catalog returns what every code means, where the problem is, and what to do about it — never guess from the name.
    - `reason_message` string, nullable, required: Human-readable reason.
    - `started_at` string, date-time, required: Execution start (ISO 8601 UTC).
    - `finished_at` string, date-time, nullable, required: Execution finish (ISO 8601 UTC).
  - `pagination` object, required
    - `next_cursor` string, nullable, required: Opaque cursor for the next page — pass as ?cursor=. Null when there are no further results.
    - `has_more` boolean, required: Whether another page exists.
    - `limit` integer, required: The page size that was applied.
    - `total_count` integer: Total rows matching the filters, ignoring paging. Present ONLY when the request passed ?include_total=true.

## Other responses

- `400`: `invalid_cursor` — The cursor is malformed, was issued for a different query, or (aging) the report changed. Restart without cursor, keeping the filters identical. `validation_failed` — The request failed schema validation. See error.details for field messages.
- `401`: `invalid_credentials` — The credential is malformed or does not match an active key. The response never reveals whether a key identifier exists. `missing_credentials` — No Authorization: Bearer header was sent. `revoked_credentials` — The presented key was revoked. Create a new key in Settings → API.
- `403`: `feature_unavailable` — The tenant's tier does not currently include API access. Feature rollout flags cannot grant this entitlement. `permission_denied` — The key's permission does not allow this operation (readonly keys cannot call admin-only operations).
- `404`: `not_found` — No such resource in YOUR tenant. Ids belonging to another tenant are indistinguishable from missing ones.
- `429`: `rate_limit_exceeded` — Too many requests. Honor the Retry-After header (seconds) before retrying — waiting that long is enough. The RateLimit-* fields on every response say how much headroom is left before this happens; pace against them instead of retrying into a refusal.
- `500`: `internal_error` — Unexpected server error. Safe to retry with the same Idempotency-Key.

---

[API](https://skmtc.dev/getfinero/apis/finero-public-api.md) · [All operations](https://skmtc.dev/getfinero/apis/finero-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getfinero/apis/finero-public-api/revisions/3d456e222775?raw)
