---
title: "Retrieve a workflow's step graph"
method: GET
path: "/api/v1/workflows/{id}/graph"
tags: ["Workflows"]
---

# Retrieve a workflow's step graph

`GET /api/v1/workflows/{id}/graph`

## Request

- Base URL: `https://api.sendly.now`
- URL: `https://api.sendly.now/api/v1/workflows/{id}/graph`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `better-auth.session_token`
  - OAuth 2 (authorization code, authorization URL `https://app.sendly.now/api/auth/oauth2/authorize`, token URL `https://app.sendly.now/api/auth/oauth2/token`, scopes: `workflows:read`)

Every step in the workflow, including its `TRIGGER` entry node, and every directed transition between them. `version` is the workflow's version at the time of the read — a different number on a later read means somebody edited the graph in between.

A step's `config` is returned exactly as stored, camelCase keys and all, rather than projected into the snake_case used everywhere else on this API. That is deliberate: the same document is authored by the visual editor, and renaming its keys on the way out would mean any key this API did not know about was silently dropped on the way back in.

The response of `GET /api/v1/workflows/{id}/graph` is accepted verbatim by `PUT` on the same path: read a graph, change a step, send it back. Step and transition ids are yours to choose on a write, which is what makes that round trip a no-op rather than a rebuild.

Requires the `workflows:read` scope — View your automation workflows and their runs.

## Path parameters

- `id` string, uuid, required: Workflow id.

## Response `200`

The workflow's graph

- WorkflowGraphV1: A workflow's complete step graph. The response of `GET /api/v1/workflows/{id}/graph` is accepted verbatim by `PUT` on the same path.
  - `steps` WorkflowStepReadV1[], required
    - `config` object, required: The step's configuration, exactly as stored. See `WorkflowStepV1` for the keys each step type uses; keys are camelCase.
    - `id` string, uuid, required: Stable step id. On a graph write it is CHOSEN BY THE CALLER: send back the id you read to keep a step (and its run history), a fresh uuid to add one, and omit an id to delete that step.
    - `name` string, required
    - `position` WorkflowStepPositionV1, required: Where this step sits on the editor canvas.
      - `x` number, required
      - `y` number, required
    - `template_id` string, uuid, nullable: The `SEND_EMAIL`/`SEND_AT_OPTIMAL_TIME` template, as a relation. Null for every other step type.
    - `type` 'TRIGGER' | 'SEND_EMAIL' | 'DELAY' | 'WAIT_FOR_EVENT' | 'CONDITION' | 'EXIT' | 'WEBHOOK' | 'UPDATE_CONTACT' | 'SEND_AT_OPTIMAL_TIME', required
  - `transitions` WorkflowTransitionV1[], required
    - `condition` union, required: Null to always follow this edge. From a `CONDITION` step, `{ "branch": "yes" }`, `{ "branch": "no" }`, or `{ "branch": "<branch id>" }` in the multi form.
      - string
      - number
      - boolean
      - object
    - `from_step_id` string, uuid, required
    - `id` string, uuid, required: Caller-chosen on a write, exactly like a step id.
    - `priority` integer, required: Evaluation order among the edges leaving one step; lowest first.
    - `to_step_id` string, uuid, required
  - `version` integer, required: The workflow's version AFTER this read. Every structural change bumps it and writes a `workflow_versions` snapshot, so a changed number between two reads means somebody edited the graph.
  - `workflow_id` string, uuid, required

## Other responses

- `401`: `invalid_api_key` or `invalid_session` — missing or invalid credentials.
- `403`: `scope_missing`, `project_access_denied`, or `project_disabled`.
- `404`: `resource_not_found` — no workflow with this id belongs to the authenticated project.
- `422`: `validation_error` — query, path, or body parameters did not match the schema.
- `429`: `rate_limited` — see `Retry-After` and the `RateLimit` headers.
- `500`: `internal_error`.

---

[API](https://skmtc.dev/sendly/apis/sendly-api.md) · [All operations](https://skmtc.dev/sendly/apis/sendly-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sendly/apis/sendly-api/revisions/ce7cfb7f7c7e?raw)
