> ## 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.

# Subir o Flow JSON

> Sobe o Flow JSON de um Flow ainda em `DRAFT`.

**A Meta responde `200` com as recusas dentro do corpo — este endpoint não.** `POST /flows/{id}/assets` devolve HTTP 200 carregando `validation_errors` quando recusa o documento, e o cliente que lê só o status conclui que o upload foi aceito: o editor mostra "salvo", o Flow mantém o JSON ANTERIOR, e a divergência só aparece quando um cliente abre o formulário velho em produção. Por isso este handler ignora o status do Graph e lê a lista: lista não vazia é **422 `FLOW_JSON_INVALID`** com `validationErrors` junto. Um `200` nosso sempre carrega `validationErrors: []`, e o campo sai explicitamente no sucesso para que o cliente que ramifica no status e o que ramifica na lista cheguem à mesma conclusão.

`flowJson` é uma **string**, nunca objeto aninhado: a Meta compila os bytes exatos, e re-serializar moveria as posições que os erros dela apontam. A lista volta verbatim, sem tradução — o formato é da Meta. O corpo aceita apenas `flowJson`. Permissão `flows:manage`.

**Exige chave com escopo de número.** Uma chave de tenant precisa nomear o número no header `x-whatsapp-number-id`, senão recebe 403 `TENANT_SCOPE_NOT_ALLOWED`.



## OpenAPI

````yaml openapi.pt.json POST /v1/flows/{id}/json
openapi: 3.1.0
info:
  title: API Pilot Status
  version: 1.0.0
  license:
    name: Pilot Status Terms of Service
    url: https://pilotstatus.com.br/terms
  description: >-
    API REST pública do Pilot Status. Autentique com o header `x-api-key:
    ps_...` (ou `x-api-key-id`). Base URL: https://pilotstatus.com.br
servers:
  - url: https://pilotstatus.com.br
security:
  - apiKey: []
  - apiKeyId: []
paths:
  /v1/flows/{id}/json:
    post:
      tags:
        - Flows
      summary: Subir o Flow JSON
      description: >-
        Sobe o Flow JSON de um Flow ainda em `DRAFT`.


        **A Meta responde `200` com as recusas dentro do corpo — este endpoint
        não.** `POST /flows/{id}/assets` devolve HTTP 200 carregando
        `validation_errors` quando recusa o documento, e o cliente que lê só o
        status conclui que o upload foi aceito: o editor mostra "salvo", o Flow
        mantém o JSON ANTERIOR, e a divergência só aparece quando um cliente
        abre o formulário velho em produção. Por isso este handler ignora o
        status do Graph e lê a lista: lista não vazia é **422
        `FLOW_JSON_INVALID`** com `validationErrors` junto. Um `200` nosso
        sempre carrega `validationErrors: []`, e o campo sai explicitamente no
        sucesso para que o cliente que ramifica no status e o que ramifica na
        lista cheguem à mesma conclusão.


        `flowJson` é uma **string**, nunca objeto aninhado: a Meta compila os
        bytes exatos, e re-serializar moveria as posições que os erros dela
        apontam. A lista volta verbatim, sem tradução — o formato é da Meta. O
        corpo aceita apenas `flowJson`. Permissão `flows:manage`.


        **Exige chave com escopo de número.** Uma chave de tenant precisa nomear
        o número no header `x-whatsapp-number-id`, senão recebe 403
        `TENANT_SCOPE_NOT_ALLOWED`.
      operationId: post_flows_id_json
      parameters:
        - name: id
          in: path
          required: true
          description: >-
            O id **local** do Flow — o campo `id` que `GET /v1/flows` devolve,
            nunca o `metaFlowId`.
          schema:
            type: string
          example: cmf1a2b3c4d5e6f7g8h9i0j1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - flowJson
              properties:
                flowJson:
                  type: string
                  description: O Flow JSON completo, como STRING.
                  example: '{"version":"7.1","screens":[]}'
      responses:
        '200':
          description: Aceito. `validationErrors` está sempre presente e sempre vazio aqui
          content:
            application/json:
              example:
                id: cmf1a2b3c4d5e6f7g8h9i0j1
                validationErrors: []
        '400':
          description: >-
            `FLOW_JSON_REQUIRED` (o corpo fez parse e `flowJson` está ausente ou
            vazio — distinto de `FLOW_BODY_INVALID`, que é o corpo não ter feito
            parse), `FLOW_UNKNOWN_FIELDS`, ou recusa da Meta
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Metade em português
                  errorEN:
                    type: string
                    description: Metade em inglês
                  code:
                    type: string
              example:
                error: >-
                  Envie um corpo JSON com o campo flowJson: o Flow JSON
                  completo, como STRING.
                errorEN: >-
                  Send a JSON body with a flowJson field: the complete Flow
                  JSON, as a STRING.
                code: FLOW_JSON_REQUIRED
        '401':
          description: Header `x-api-key` / `x-api-key-id` ausente ou inválido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Unauthorized
        '403':
          description: >-
            Chave com escopo de tenant usada em endpoint com escopo de número,
            ou o papel da chave não tem a permissão
          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: >-
            Nenhum Flow com esse id dentro da WABA da própria chave. Nunca 403:
            um Flow de outro tenant é indistinguível de um que não existe, de
            propósito — um 403 confirmaria o id alheio a quem o adivinhou
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Metade em português
                  errorEN:
                    type: string
                    description: Metade em inglês
                  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: >-
            O Flow saiu de `DRAFT`. Publicar é irreversível na Meta — clone para
            começar uma versão nova
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Metade em português
                  errorEN:
                    type: string
                    description: Metade em inglês
                  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: >-
            O CONTEÚDO do documento foi recusado. DUAS causas, distinguidas pelo
            `code`: `FLOW_JSON_INVALID` — a Meta recusou, e `validationErrors`
            traz a lista dela, verbatim (é essa a resposta a ler, não um 200).
            `FLOW_JSON_DEAD_FORM_PREFIX` — NÓS recusamos, antes de a Meta ver: o
            documento referencia valores pelo NOME do componente `Form`
            (`${form_produto.qtd}`) onde só a palavra-chave literal `form`
            resolve (`${form.qtd}`). A Meta aceita esse documento e não acusa
            erro, e em execução entrega `"data": {}` ao seu endpoint. `deadRefs`
            traz a substituição pronta de cada referência.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  errorEN:
                    type: string
                  code:
                    type: string
                  validationErrors:
                    type: array
                    items: {}
                    description: >-
                      A lista da Meta, sem tradução nem reformatação. O formato
                      é da Meta e pode mudar sem aviso.
                  deadRefs:
                    type: array
                    description: >-
                      Só em `FLOW_JSON_DEAD_FORM_PREFIX`. Uma entrada por
                      referência que não se resolve, cada uma já com a
                      substituição escrita por extenso.
                    items:
                      type: object
                      properties:
                        ref:
                          type: string
                        suggestion:
                          type: string
              examples:
                metaRefused:
                  summary: FLOW_JSON_INVALID — a Meta recusou o documento
                  value:
                    error: >-
                      A Meta recusou este Flow JSON. Veja validationErrors: a
                      lista é a resposta dela, sem tradução.
                    errorEN: >-
                      Meta rejected this Flow JSON. See validationErrors: the
                      list is Meta's own answer, untranslated.
                    code: FLOW_JSON_INVALID
                    validationErrors:
                      - error: INVALID_PROPERTY
                        error_type: JSON_SCHEMA_ERROR
                        message: The property "foo" is not expected
                        line_start: 12
                        line_end: 12
                        column_start: 5
                        column_end: 9
                deadFormPrefix:
                  summary: >-
                    FLOW_JSON_DEAD_FORM_PREFIX — recusado pelo Pilot Status
                    antes de a Meta vê-lo
                  value:
                    error: >-
                      Este Flow JSON referencia valores pelo NOME DO FORM. Use a
                      forma `${form.campo}` nas referências listadas em
                      deadRefs.
                    errorEN: >-
                      This Flow JSON references values by the FORM'S NAME. Use
                      the `${form.field}` form in the references listed in
                      deadRefs.
                    code: FLOW_JSON_DEAD_FORM_PREFIX
                    deadRefs:
                      - ref: ${form_produto.quantidade}
                        suggestion: ${form.quantidade}
        '429':
          description: Limite de taxa excedido
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Too many requests
        '500':
          description: Erro interno. Nunca carrega a mensagem interna — essa fica no log
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Metade em português
                  errorEN:
                    type: string
                    description: Metade em inglês
                  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: Sua chave de API ps_
    apiKeyId:
      type: apiKey
      in: header
      name: x-api-key-id
      description: Id da chave de API (alternativa ao x-api-key)

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.