---
title: "Publish Flow"
method: POST
path: "/api/v1/flows/{id}/publish"
tags: ["flows"]
---

# Publish Flow

`POST /api/v1/flows/{id}/publish`

## Request

- Base URL: `https://app.blueticked.com`
- URL: `https://app.blueticked.com/api/v1/flows/{id}/publish`
- Auth: HTTP bearer

Publish a valid WhatsApp Flow draft to Meta.

Publishing requires a connected WABA and valid Flow definition.

`channel_id` (optional) picks which connected WhatsApp number the Flow publishes through. Resolution order: your explicit `channel_id`, then the channel the Flow was last published with, then the first connected WhatsApp channel. The Flow is pinned to the resolved number's Flows encryption key (dynamic forms decrypt against it), so multi-number workspaces should always pass it.

This route honours the `Idempotency-Key` header. Publish is the module's most side-effectful call (a republish clones a NEW Meta flow), and a retried request with the same key replays the first response for 24 hours instead of cloning again.

The response is the full flow row plus a nested `publish` object: on a republish `republished` is true and `previous_meta_flow_id` / `previous_deprecated` / `templates_referencing_previous` / `automations_*` report what happened to the superseded flow and everything that referenced it.

A blu_test_ (sandbox) key never publishes to Meta: it returns a dry-run shape (`{ id, name, status, test_mode: true, published: false, publish: { simulated: true, would_publish: true, republished } }`) with the local row left unpublished.

## Path parameters

- `id` string, required

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `channel_id` string, uuid, nullable

## Response `200`

Success

- object
  - `organization_id` string, uuid, required
  - `business_id` string, uuid, nullable, required
  - `definition_updated_at` string, date-time, nullable, required
  - `id` string, uuid, required
  - `name` string, required
  - `description` string, nullable, required
  - `status` 'draft' | 'published' | 'deprecated', required
  - `meta_flow_id` string, nullable, required
  - `meta_flow_version` number, nullable, required
  - `definition` object, required
  - `public_key` string, nullable, required
  - `last_synced_at` string, date-time, nullable, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `publish` object, required
    - `republished` boolean, required
    - `resumed` boolean, required
    - `previous_meta_flow_id` string, nullable, required
    - `previous_deprecated` boolean, required
    - `templates_referencing_previous` unknown[], required
      - unknown
    - `automations_relinked` unknown[], required
      - unknown
    - `automations_relink_failed` unknown[], required
      - unknown
    - `automations_referencing_previous` unknown[], required
      - unknown
  - `request_id` string, required
  - `preset_id` string, nullable

## Other responses

- `400`: Validation failed
- `401`: Unauthorized: missing or invalid API key
- `402`: Insufficient wallet balance
- `403`: Forbidden: scope, plan limit, or suspension
- `404`: Not found
- `409`: Conflict (idempotency-key reuse or resource in use)
- `413`: Request body above the endpoint's size limit
- `422`: Understood but refused: the request is well-formed, the action is not permitted for this resource
- `429`: Rate limited
- `500`: Internal error
- `502`: An upstream provider refused or failed the request
- `503`: Channel or send queue unavailable

---

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