# Get a workflow

**GET** `/api/embed/v1/accounts/{accountId}/workflows/{workflowId}`

Returns one of an account’s workflows. Never its steps.

Needs a partner key: `Authorization: Bearer gre_…`, from [Platform › Partner keys](https://docs.gorunner.io/embed/platform-screens#partner-keys). Call it from your server only.

Embed · Self-hosted with an Embed license

## Parameters

### Path

- `accountId` · Required · string: Your ID for the customer’s account: 1 to 255 bytes of UTF-8, case-sensitive. URL-encode it: it may contain `/`.
- `workflowId` · Required · UUID: The workflow’s ID, as the install or the list answered it.

## The webhook address

`webhookUrl` is where a webhook workflow takes deliveries, once its first publish or save has made the address. To start one you installed, enable it and read this field. Only these two reads carry it, never the answer of an install, enable or disable.

It works while the workflow is `live` and answers `404` otherwise. It starts production runs with no other credential, so hold it as you hold your key. It stays the same across enable and disable.

## Responses

- 200 OK

  The workflow.

- 400 `VALIDATION_ERROR`

  The account ID isn’t allowed as written. `details.field` names it.

- 404 `NOT_FOUND`

  No such account, or no such workflow in it.

- 500 `INTERNAL_ERROR`

  Something failed on the installation’s side. Try again.

Any call can also answer: [`401 UNAUTHORIZED`](https://docs.gorunner.io/errors#UNAUTHORIZED) · [`403 EMBED_NOT_LICENSED`](https://docs.gorunner.io/errors#EMBED_NOT_LICENSED) · [`403 IP_NOT_ALLOWED`](https://docs.gorunner.io/errors#IP_NOT_ALLOWED) · [`429 RATE_LIMITED`](https://docs.gorunner.io/errors#RATE_LIMITED) · [`503 BUSY`](https://docs.gorunner.io/errors#BUSY). See [Errors](https://docs.gorunner.io/embed/api#errors).

Request

**curl**

```bash
GORUNNER="https://automations.example.com"
GORUNNER_EMBED_KEY="YOUR_PARTNER_KEY"  # gre_…
ACCOUNT_ID="acct-bakery"
WORKFLOW_ID="your-workflow-id"

URL="$GORUNNER/api/embed/v1/accounts/$ACCOUNT_ID/"
URL="${URL}workflows/$WORKFLOW_ID"
curl "$URL" \
  -H "Authorization: Bearer $GORUNNER_EMBED_KEY"
```

**JavaScript**

```js
const GORUNNER = "https://automations.example.com";
const KEY = process.env.GORUNNER_EMBED_KEY; // gre_…
const ACCOUNT_ID = encodeURIComponent("acct-bakery");
const WORKFLOW_ID = encodeURIComponent("your-workflow-id");

const res = await fetch(
  `${GORUNNER}/api/embed/v1/accounts/` +
    `${ACCOUNT_ID}/workflows/${WORKFLOW_ID}`,
  {
    headers: { Authorization: `Bearer ${KEY}` },
  },
);
const { data } = await res.json();
```

**Python**

```python
import os, requests
from urllib.parse import quote

GORUNNER = "https://automations.example.com"
KEY = os.environ["GORUNNER_EMBED_KEY"]  # gre_…
ACCOUNT_ID = quote("acct-bakery", safe="")
WORKFLOW_ID = quote("your-workflow-id", safe="")

res = requests.get(
    f"{GORUNNER}/api/embed/v1/accounts/"
    f"{ACCOUNT_ID}/workflows/{WORKFLOW_ID}",
    headers={"Authorization": f"Bearer {KEY}"},
)
data = res.json()["data"]
```

Response · 200 OK

```json
{
  "data": {
    "id": "3b1e5c2a-7d4f-4e8b-a1c6-5f2d9b0e7a31",
    "name": "New orders to Sheets",
    "description": "Adds each new order as a row.",
    "status": "live",
    "triggerType": "webhook",
    "workspace": {
      "id": null,
      "default": true
    },
    "templateId": "9c4e2a17-3d5b-4f86-b0e2-8a1c7d3f5e29",
    "createdAt": "2026-10-20T08:00:00Z",
    "updatedAt": "2026-10-25T09:00:00Z",
    "webhookUrl": "https://automations.example.com/api/webhooks/2f4c8e1a-6b3d-4f7e-9a05-c1d2e3f4a5b6"
  }
}
```

**Every field**

It takes no body.

### Response · 200 OK

- `data` · object
  - `id` · UUID
  - `name` · string
  - `description` · string
  - `status` · string: `draft`: never published; `live`: its trigger is on; `paused`: published, trigger off. One of `draft`, `live`, `paused`.
  - `triggerType` · string
  - `workspace` · object
    - `id` · string or null: The partner’s workspace id; null for the default workspace.
    - `default` · boolean
  - `templateId` · UUID or null: The template it was installed from.
  - `webhookUrl` · URL: Where this workflow takes deliveries (`POST /api/webhooks/{token}`): on a webhook-triggered workflow, once its first publish or save has made the address, and only in the two reads, `GET.../workflows` and `GET.../workflows/{workflowId}` (`Cache-Control: no-store`), never in a write’s answer, which an `Idempotency-Key` can keep for a day. It takes deliveries while the workflow is `live` and answers 404 otherwise. It starts production runs with no other credential: hold it as you hold this key. It stays the same across enable and disable, and changes only when a token rotates it (`POST /api/workflows/{id}/webhook/rotate`). Absent otherwise.
  - `createdAt` · time
  - `updatedAt` · time

Related: [List workflows](https://docs.gorunner.io/embed/api/workflows/list-workflows)

Source: https://docs.gorunner.io/embed/api/workflows/get-workflow
