---
title: "Create a workflow"
method: POST
path: "/workflows"
tags: ["Workflows"]
---

# Create a workflow

`POST /workflows`

## Request

- Base URL: `https://api.reacherapp.com/public/v1`
- URL: `https://api.reacherapp.com/public/v1/workflows`
- Auth: API key in header `x-api-key` and API key in header `x-shop-id`

Create a draft. A draft sends nothing: it reaches creators only at `POST /workflows/{id}/publish`. Requires `read_write` scope and an `Idempotency-Key`. Validate first with `POST /workflows/validate` — a definition with blocking issues saves fine but cannot be published.

## Headers

- `Idempotency-Key` string, nullable

## Request body

- WorkflowCreateBody
  - `definition` object, required: The workflow document: `name`, a `trigger` and its `steps`. Validated strictly on the way in. GET /workflows/templates returns working examples, GET /workflows/conditions the rule vocabulary for this shop, and POST /workflows/validate reports what is wrong with one.
  - `settings` object, nullable: Exclusions (`groups`, `lists`, `blacklist`), `dailyMessageLimits` and `dailyInviteLimits` keyed by weekday, `skipCreatorsInOtherWorkflows`, and `timezone` — which decides when the daily budget resets.
  - `created_from` object, nullable: Provenance, e.g. `{"type": "template", "template_id": "..."}`.

## Response `201`

Successful Response

- EnvelopeWorkflowPublic
  - `data` WorkflowPublic, required: One workflow with both documents.
    - `workflow_id` string, required
    - `shop_id` integer, required
    - `name` string, required
    - `description` string, nullable
    - `status` string, required: draft, running, paused, archived or template.
    - `version` integer, required: Incremented on each publish.
    - `trigger_type` string, required: creator_matches or recurring.
    - `step_count` integer, required
    - `branch_count` integer, required
    - `has_unpublished_changes` boolean, required: The draft differs from what the runtime is walking.
    - `created_from` object, nullable
    - `published_at` string, nullable
    - `created_at` string, required
    - `updated_at` string, required
    - `enrolled` integer: Creators the trigger has admitted.
    - `in_progress` integer: Creators still walking it.
    - `sends` integer
    - `reached` integer
    - `gmv` number
    - `definition` object, required: The draft being edited. The workflow document. Not schematized here, because the node set still grows and this is also Cruva's `formatVersion: 1` format — but it IS validated: an unknown step type is refused, unknown keys are dropped, and defaults are filled in on read, so this is not byte-identical to what was written. GET /workflows/templates returns working examples and GET /workflows/conditions the rule vocabulary for this shop.
    - `published_definition` object, nullable: What the runtime is actually walking, or null if never published. Differs from `definition` whenever `has_unpublished_changes` is true.
    - `settings` object, required: Exclusions, daily message and invite limits, and timezone — the DRAFT settings, the pair of `definition`. A running workflow uses the settings captured at its last publish, so when `has_unpublished_changes` is true these are not yet the ones governing live outreach. There is no published-settings field to read them from yet (CORE-8947).

## Other responses

- `400`: The document was rejected — an unreadable definition, an unknown step type, a daily limit above the ceiling, a non-HTTPS image URL — or the Idempotency-Key is missing or malformed.
- `403`: API key lacks `read_write` scope (`WRITE_NOT_PERMITTED`), or names a shop it is not granted.
- `404`: No such workflow in this shop.
- `409`: Idempotency conflict, or the workflow is not in a state that allows this transition.
- `422`: The request body is the wrong shape — an unknown top-level key, or a field of the wrong type.
- `429`: Write-tier rate limit (10/min, 50/hr, 100/day) exceeded.

## Changes

> 76 revisions in range; 1 not diffed.

- **2026-10-20** `9353ed4982e8`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/reacherapp/apis/reacher-data-api/changes/workflows/post.md)

---

[API](https://skmtc.dev/reacherapp/apis/reacher-data-api.md) - [All operations](https://skmtc.dev/reacherapp/apis/reacher-data-api/llms.txt) - [OpenAPI document](https://skmtc.dev/reacherapp/apis/reacher-data-api/revisions/63ce74b30b5a?raw)
