> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pilotstatus.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Create or clone Flow

> Creates a Flow in `DRAFT`, or clones an existing one. Answers `201` with `{id, metaFlowId}` — the two fields only, not the whole Flow. Accepts exactly `name`, `categories` and `cloneFromFlowId`: any other key is REFUSED with 400 `FLOW_UNKNOWN_FIELDS`, never ignored, so `{"status":"PUBLISHED"}` cannot answer 201 and let you conclude you published. The number and its WABA come from the key — sending `whatsappNumberId`, `wabaId` or `metaWabaId` is 400 `FLOW_NUMBER_FROM_KEY`. Permission `flows:manage` (ADMIN and above).

**Requires a number-scoped key.** A tenant-scoped key must name the number with the `x-whatsapp-number-id` header, or it gets 403 `TENANT_SCOPE_NOT_ALLOWED`.



## OpenAPI

````yaml openapi.json POST /v1/flows
openapi: 3.1.0
info:
  title: Pilot Status API
  version: 1.0.0
  license:
    name: Pilot Status Terms of Service
    url: https://pilotstatus.com.br/terms
  description: >-
    Public REST API for Pilot Status. Authenticate with the `x-api-key: ps_...`
    header (or `x-api-key-id`). Base URL: https://pilotstatus.com.br
servers:
  - url: https://pilotstatus.com.br
security:
  - apiKey: []
  - apiKeyId: []
paths:
  /v1/flows:
    post:
      tags:
        - Flows
      summary: Create or clone Flow
      description: >-
        Creates a Flow in `DRAFT`, or clones an existing one. Answers `201` with
        `{id, metaFlowId}` — the two fields only, not the whole Flow. Accepts
        exactly `name`, `categories` and `cloneFromFlowId`: any other key is
        REFUSED with 400 `FLOW_UNKNOWN_FIELDS`, never ignored, so
        `{"status":"PUBLISHED"}` cannot answer 201 and let you conclude you
        published. The number and its WABA come from the key — sending
        `whatsappNumberId`, `wabaId` or `metaWabaId` is 400
        `FLOW_NUMBER_FROM_KEY`. Permission `flows:manage` (ADMIN and above).


        **Requires a number-scoped key.** A tenant-scoped key must name the
        number with the `x-whatsapp-number-id` header, or it gets 403
        `TENANT_SCOPE_NOT_ALLOWED`.
      operationId: post_flows
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - categories
              properties:
                name:
                  type: string
                  minLength: 1
                  description: Flow name. Non-empty; trimmed.
                  example: Agendamento v2
                categories:
                  type: array
                  minItems: 1
                  items:
                    type: string
                    enum:
                      - SIGN_UP
                      - SIGN_IN
                      - APPOINTMENT_BOOKING
                      - LEAD_GENERATION
                      - CONTACT_US
                      - CUSTOMER_SUPPORT
                      - SURVEY
                      - OTHER
                  description: >-
                    One or more of Meta's closed set. A value outside it is 400
                    `FLOW_CATEGORY_INVALID`.
                  example:
                    - APPOINTMENT_BOOKING
                cloneFromFlowId:
                  type: string
                  description: >-
                    The **LOCAL** id of the source Flow — the `id` field `GET
                    /v1/flows` returns, **never** the `metaFlowId`. Confusing
                    the two is the natural mistake and we cannot detect it for
                    you: both are opaque strings, and Meta answers with its own
                    error. `metaFlowId` is also nullable (a draft never pushed),
                    so an id from Meta would have nothing to resolve. Omit to
                    create from scratch; `null` is refused.
                  example: cmf1a2b3c4d5e6f7g8h9i0j1
            example:
              name: Agendamento v2
              categories:
                - APPOINTMENT_BOOKING
              cloneFromFlowId: cmf1a2b3c4d5e6f7g8h9i0j1
      responses:
        '201':
          description: Flow created in DRAFT
          content:
            application/json:
              example:
                id: cmf1a2b3c4d5e6f7g8h9i0j1
                metaFlowId: '1122334455'
        '400':
          description: >-
            `FLOW_BODY_INVALID` (the payload did not parse),
            `FLOW_NAME_REQUIRED`, `FLOW_CATEGORY_INVALID`,
            `FLOW_CLONE_SOURCE_INVALID`, `FLOW_UNKNOWN_FIELDS`,
            `FLOW_NUMBER_FROM_KEY`, or a Meta (Graph) refusal
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: >-
                  categories é obrigatório: uma lista não vazia de SIGN_UP,
                  SIGN_IN, APPOINTMENT_BOOKING, LEAD_GENERATION, CONTACT_US,
                  CUSTOMER_SUPPORT, SURVEY, OTHER.
                errorEN: >-
                  categories is required: a non-empty array of SIGN_UP, SIGN_IN,
                  APPOINTMENT_BOOKING, LEAD_GENERATION, CONTACT_US,
                  CUSTOMER_SUPPORT, SURVEY, OTHER.
                code: FLOW_CATEGORY_INVALID
        '401':
          description: Missing or invalid `x-api-key` / `x-api-key-id` header
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Unauthorized
        '403':
          description: >-
            Tenant-scoped key used on a number-scoped endpoint, or the key's
            role lacks the permission
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Tenant-scoped keys cannot call number endpoints
                code: TENANT_SCOPE_NOT_ALLOWED
        '404':
          description: >-
            `cloneFromFlowId` names no Flow of yours. On this verb it is the
            only id you supply
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: Flow não encontrado para o número desta chave.
                errorEN: Flow not found for this key's number.
                code: FLOW_NOT_FOUND
        '409':
          description: >-
            The Flow has left `DRAFT`. Publishing is irreversible on Meta —
            clone it to start a new version
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: >-
                  Este Flow já foi publicado na Meta e não pode mais ser
                  alterado. Clone-o para criar uma nova versão.
                errorEN: >-
                  This Flow is already published on Meta and can no longer be
                  changed. Clone it to create a new version.
                code: FLOW_NOT_DRAFT
        '422':
          description: >-
            The key's number is not a Meta (Cloud API) number, or has no WABA
            behind it
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: >-
                  Flows existem apenas em números Meta (API Oficial). O número
                  desta chave não é Meta ou não tem uma WABA associada — use uma
                  chave de um número Meta.
                errorEN: >-
                  Flows only exist on Meta (Cloud API) numbers. This key's
                  number is not a Meta number, or has no WABA behind it — use a
                  key bound to a Meta number.
                code: FLOW_REQUIRES_META_NUMBER
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Too many requests
        '500':
          description: >-
            Internal error. Never carries the internal message — that belongs in
            the log
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: Erro interno do servidor.
                errorEN: Internal server error.
                code: INTERNAL_ERROR
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Your ps_ API key
    apiKeyId:
      type: apiKey
      in: header
      name: x-api-key-id
      description: API key id (alternative to x-api-key)

````