{
  "openapi": "3.1.0",
  "info": {
    "title": "API do InstaCRM",
    "version": "1.1.0",
    "description": "API do InstaCRM para sistemas de fora (ERP, loja, n8n, Make, Zapier).\n\n**Chave:** em todo pedido, `Authorization: Bearer <chave>` (ou `X-Api-Key`). A chave é criada no CRM em **API e Webhooks**, diz a empresa e age em nome de quem a criou, limitada às permissões marcadas nela.\n\n**Achar o cliente:** onde aparece `{ref}`, use `ext:<código do seu sistema>`, `tel:<telefone>`, `cpf:<cpf>` (exige `dados-pessoais:ler`) ou o id do CRM.\n\n**Sem repetir:** nas rotas que fazem alguma coisa, mande `Idempotency-Key`. Repetir o pedido com a mesma chave devolve a mesma resposta e não faz de novo (vale 24 h).\n\n**Erros:** sempre `{ \"erro\": { \"codigo\", \"mensagem\", \"detalhes\"? } }`. Compare o `codigo`. Toda resposta traz `X-Pedido-Id`.\n\n**Ritmo:** 120 pedidos/min por chave e 600/min por empresa (`X-Ritmo-Limite`, `X-Ritmo-Restante`; acima, 429 com `Retry-After`). Mensagem avulsa e resposta em conversa dividem um teto: 30/min e 1.000/dia por empresa. Ligações: 10/min e 200/dia.\n\n**Plano:** as rotas de módulos contratados à parte (campanhas, cadastro de etiquetas, agenda, relatórios, ligações) respondem 403 `modulo_nao_contratado` quando o plano da empresa não inclui o módulo — a mesma regra das telas.\n\n**Chave de teste** (`icrm_test_…`): confere tudo (permissão, alcance, dados) e responde `\"simulado\": true` sem gravar, enviar, publicar ou ligar.\n\n**Avisos (webhooks):** POST assinado com `X-InstaCRM-Assinatura: t=<unix>,v1=<HMAC-SHA256 de \"<t>.<corpo>\">`. Responda 2xx em até 10 s; o mesmo aviso pode chegar duas vezes (use o `id`).",
    "license": {
      "name": "Uso restrito às empresas clientes do InstaCRM",
      "identifier": "LicenseRef-InstaCRM-Proprietaria"
    }
  },
  "servers": [
    {
      "url": "https://app.nossoia.com/api/v1"
    }
  ],
  "security": [
    {
      "chave": []
    },
    {
      "chaveNoCabecalho": []
    }
  ],
  "tags": [
    {
      "name": "Conta",
      "description": "Quem é a chave, as conexões da empresa e esta especificação."
    },
    {
      "name": "Clientes",
      "description": "Cadastro de clientes (leads): criar, atualizar pelo código do seu sistema, buscar e mover no funil."
    },
    {
      "name": "Etiquetas",
      "description": "Etiquetas no cliente — com a automação da etiqueta rodando como na tela."
    },
    {
      "name": "Mensagens",
      "description": "Mensagem pelo WhatsApp, com os freios do CRM: texto, arquivo, voz, template completo, botões, lista, carrossel, localização, contato, enquete e Pix; reagir, editar e apagar."
    },
    {
      "name": "Disparos",
      "description": "Campanhas pelo mesmo motor anti-banimento da tela."
    },
    {
      "name": "Publicações",
      "description": "Instagram (foto, carrossel, Reels, Story) e Status do WhatsApp."
    },
    {
      "name": "Atendimento",
      "description": "As conversas de todos os canais: ler, responder (com botões, lista, carrossel, localização, contato, enquete e Pix), visto e digitando, atribuir, transferir, devolver para a IA, encerrar, notas e mensagens agendadas."
    },
    {
      "name": "Grupos",
      "description": "Grupos de WhatsApp pela conexão por QR code: listar, ver quem está, mandar mensagem, criar, pôr e tirar pessoas, convite e sair."
    },
    {
      "name": "Agenda",
      "description": "Compromissos da equipe pelas mesmas travas da tela e da IA: expediente, conflito e horário passado."
    },
    {
      "name": "Tarefas",
      "description": "A próxima ação sobre um cliente: criar, remarcar, concluir."
    },
    {
      "name": "Relatórios (BI)",
      "description": "Os conjuntos do Power BI na mesma chave — para planilha, BI ou data lake."
    },
    {
      "name": "Ligações",
      "description": "Ligações com IA pelo WhatsApp e pelo telefone (VoIP), e o que aconteceu em cada uma."
    },
    {
      "name": "Administração",
      "description": "Usuários, equipes e filas. Administrador e a pessoa dona da chave não se alteram por aqui, e a API não define senha: manda o convite."
    },
    {
      "name": "Avisos (webhooks)",
      "description": "Os endereços do seu sistema que recebem os avisos assinados."
    }
  ],
  "paths": {
    "/eu": {
      "get": {
        "operationId": "get_eu",
        "tags": [
          "Conta"
        ],
        "summary": "Quem é esta chave",
        "description": "Empresa, permissões da chave, em nome de quem ela age e os limites de ritmo. Bom para testar a chave.\n\n**Permissão da chave:** qualquer chave válida.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "get_openapi_json",
        "tags": [
          "Conta"
        ],
        "summary": "Especificação OpenAPI",
        "description": "Esta API inteira em OpenAPI 3.1 — rotas, permissões, exemplos, erros e os avisos (webhooks). Importe no Postman, no Insomnia ou no nó HTTP do n8n.\n\n**Permissão da chave:** qualquer chave válida.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        }
      }
    },
    "/canais": {
      "get": {
        "operationId": "get_canais",
        "tags": [
          "Conta"
        ],
        "summary": "Conexões da empresa",
        "description": "Lista as conexões (WhatsApp oficial, WhatsApp por QR, Instagram…) com o número de cada uma — o \"canal\" que as outras rotas pedem. Cada canal diz também a \"situacao\" de agora: QR = conectado, desconectado ou desconhecido; oficial = ok, limitado (só marketing travado) ou travado, com \"motivo\" e \"ate\".\n\n**Permissão da chave:** qualquer chave válida.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        }
      }
    },
    "/clientes": {
      "post": {
        "operationId": "post_clientes",
        "tags": [
          "Clientes"
        ],
        "summary": "Criar ou atualizar cliente",
        "description": "Acha o cliente pelo codigoExterno, depois CPF, depois telefone. Se achar, atualiza só os campos enviados; se não, cria. Responde 201 quando cria e 200 quando atualiza. O cliente criado fica FORA do robô de consulta de crédito, a menos que venha \"consultar\": true com o CPF.\n\n**Permissão da chave:** `clientes:escrever` (Criar e editar clientes).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:escrever",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Maria Souza",
                "telefone": "62999998888",
                "codigoExterno": "ERP-1042",
                "email": "maria@exemplo.com",
                "etapa": "novos",
                "camposExtras": {
                  "plano": "ouro"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "get_clientes",
        "tags": [
          "Clientes"
        ],
        "summary": "Listar clientes",
        "description": "Filtros: etapa, etiqueta, codigoExterno, telefone, cpf (exige dados-pessoais:ler), atualizadoDesde (ISO). Ordem: atualizados mais antigos primeiro — ideal para sincronizar. Paginação por \"cursor\" (use o \"proximo\" da página anterior); \"limite\" até 200.\n\n**Permissão da chave:** `clientes:ler` (Ler clientes).",
        "parameters": [
          {
            "name": "etapa",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Código da etapa do funil (veja GET /v1/funil/etapas)"
          },
          {
            "name": "etiqueta",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Nome exato de uma etiqueta"
          },
          {
            "name": "codigoExterno",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O código do cliente no seu sistema"
          },
          {
            "name": "telefone",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Telefone com DDD"
          },
          {
            "name": "cpf",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "CPF — exige a permissão dados-pessoais:ler"
          },
          {
            "name": "atualizadoDesde",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Só os atualizados a partir deste instante (ISO)"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 200; padrão 50)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior (paginação)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:ler"
      }
    },
    "/clientes/lote": {
      "post": {
        "operationId": "post_clientes_lote",
        "tags": [
          "Clientes"
        ],
        "summary": "Criar ou atualizar até 500 clientes",
        "description": "Mesma regra da rota simples, um por um. A resposta traz o resultado de cada item — um item ruim não derruba os outros.\n\n**Permissão da chave:** `clientes:escrever` (Criar e editar clientes).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:escrever",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "clientes": [
                  {
                    "nome": "João",
                    "telefone": "62988887777",
                    "codigoExterno": "ERP-1"
                  },
                  {
                    "nome": "Ana",
                    "telefone": "62977776666",
                    "codigoExterno": "ERP-2"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/clientes/{ref}": {
      "get": {
        "operationId": "get_clientes_ref",
        "tags": [
          "Clientes"
        ],
        "summary": "Ver um cliente",
        "description": ":ref pode ser o id do CRM, ext:<código do ERP>, tel:<telefone> ou cpf:<cpf> (este exige dados-pessoais:ler).\n\n**Permissão da chave:** `clientes:ler` (Ler clientes).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:ler"
      },
      "patch": {
        "operationId": "patch_clientes_ref",
        "tags": [
          "Clientes"
        ],
        "summary": "Editar cliente",
        "description": "Muda só os campos enviados. \"camposExtras\" é mesclado com o que já existe (mande \"substituirCamposExtras\": true para trocar tudo).\n\n**Permissão da chave:** `clientes:escrever` (Criar e editar clientes).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:escrever",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "telefone2": "6233334444",
                "camposExtras": {
                  "plano": "prata"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_clientes_ref",
        "tags": [
          "Clientes"
        ],
        "summary": "Excluir cliente",
        "description": "Apaga o cliente de vez — o mesmo \"excluir\" do funil, com o que a tela apaga junto. Exige a permissão \"clientes:excluir\" (sensível) e, no papel de quem é dono da chave, \"lead:excluir\". Teto: 100 por dia por empresa.\n\n**Permissão da chave:** `clientes:excluir` (Excluir clientes).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:excluir"
      }
    },
    "/clientes/{ref}/etapa": {
      "post": {
        "operationId": "post_clientes_ref_etapa",
        "tags": [
          "Clientes"
        ],
        "summary": "Mover no funil",
        "description": "Muda a etapa do funil (veja GET /v1/funil/etapas). Registra na auditoria como a tela faz.\n\n**Permissão da chave:** `clientes:escrever` (Criar e editar clientes).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:escrever",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "etapa": "negociacao"
              }
            }
          }
        }
      }
    },
    "/funil/etapas": {
      "get": {
        "operationId": "get_funil_etapas",
        "tags": [
          "Clientes"
        ],
        "summary": "Etapas do funil",
        "description": "Os códigos e nomes das etapas, na ordem do quadro.\n\n**Permissão da chave:** `clientes:ler` (Ler clientes).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "clientes:ler"
      }
    },
    "/etiquetas": {
      "get": {
        "operationId": "get_etiquetas",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Listar etiquetas",
        "description": "Todas as etiquetas da empresa, com cor, grupo e a automação de cada uma. \"?ativas=true\" traz só as ativas.\n\n**Permissão da chave:** `etiquetas:ler` (Ler etiquetas).",
        "parameters": [
          {
            "name": "ativas",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true traz só as etiquetas ativas"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:ler"
      },
      "post": {
        "operationId": "post_etiquetas",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Criar etiqueta",
        "description": "Cria uma etiqueta simples (sem automação). A automação se configura na tela de Etiquetas.\n\n**Permissão da chave:** `etiquetas:gerenciar` (Criar e editar etiquetas).\n\n**Plano:** depende do módulo `etiquetas_automacoes`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:gerenciar",
        "x-modulo": "etiquetas_automacoes",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Cliente VIP",
                "cor": "#22c55e",
                "descricao": "Compra acima de R$ 1.000"
              }
            }
          }
        }
      }
    },
    "/etiquetas/{etiqueta}": {
      "patch": {
        "operationId": "patch_etiquetas_etiqueta",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Editar etiqueta",
        "description": "Muda nome, cor, descrição ou se está ativa. A automação configurada na tela é mantida. :etiqueta é o id ou o nome.\n\n**Permissão da chave:** `etiquetas:gerenciar` (Criar e editar etiquetas).\n\n**Plano:** depende do módulo `etiquetas_automacoes`.",
        "parameters": [
          {
            "name": "etiqueta",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A etiqueta: id ou nome"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:gerenciar",
        "x-modulo": "etiquetas_automacoes",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "cor": "#f97316"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_etiquetas_etiqueta",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Excluir etiqueta",
        "description": "Apaga a etiqueta do cadastro. :etiqueta é o id ou o nome.\n\n**Permissão da chave:** `etiquetas:gerenciar` (Criar e editar etiquetas).\n\n**Plano:** depende do módulo `etiquetas_automacoes`.",
        "parameters": [
          {
            "name": "etiqueta",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A etiqueta: id ou nome"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:gerenciar",
        "x-modulo": "etiquetas_automacoes"
      }
    },
    "/clientes/{ref}/etiquetas": {
      "post": {
        "operationId": "post_clientes_ref_etiquetas",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Etiquetar um cliente",
        "description": "Põe a etiqueta no cliente. Se ele tem conversa, a AUTOMAÇÃO da etiqueta roda (mensagem, régua, fluxo, mudança de etapa), exatamente como na tela. Sem conversa, a etiqueta fica no cadastro e a resposta avisa que a mensagem da automação não saiu. Etiqueta de grupo substitui as irmãs.\n\n**Permissão da chave:** `etiquetas:aplicar` (Aplicar e remover etiquetas).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:aplicar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "etiqueta": "Cliente VIP"
              }
            }
          }
        }
      }
    },
    "/etiquetas/aplicar-em-lote": {
      "post": {
        "operationId": "post_etiquetas_aplicar_em_lote",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Etiquetar vários clientes",
        "description": "A mesma etiqueta em até 200 clientes. Cada item da lista é uma referência (ext:, tel:, id).\n\n**Permissão da chave:** `etiquetas:aplicar` (Aplicar e remover etiquetas).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:aplicar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "etiqueta": "Cliente VIP",
                "clientes": [
                  "ext:ERP-1",
                  "ext:ERP-2",
                  "tel:62999998888"
                ]
              }
            }
          }
        }
      }
    },
    "/clientes/{ref}/etiquetas/{etiqueta}": {
      "delete": {
        "operationId": "delete_clientes_ref_etiquetas_etiqueta",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Tirar etiqueta do cliente",
        "description": "Tira do cadastro e das conversas do cliente, e cancela as mensagens da régua que ainda não saíram.\n\n**Permissão da chave:** `etiquetas:aplicar` (Aplicar e remover etiquetas).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "etiqueta",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A etiqueta: id ou nome"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:aplicar"
      }
    },
    "/etiquetas/{etiqueta}/historico": {
      "get": {
        "operationId": "get_etiquetas_etiqueta_historico",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Quem recebeu a etiqueta",
        "description": "As aplicações mais recentes primeiro. Paginação: \"antesDe\" com o \"proximo\" da página anterior.\n\n**Permissão da chave:** `etiquetas:ler` (Ler etiquetas).",
        "parameters": [
          {
            "name": "etiqueta",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A etiqueta: id ou nome"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 200; padrão 50)"
          },
          {
            "name": "antesDe",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:ler"
      }
    },
    "/clientes/{ref}/gatilhos/{gatilho}": {
      "post": {
        "operationId": "post_clientes_ref_gatilhos_gatilho",
        "tags": [
          "Etiquetas"
        ],
        "summary": "Disparar um gatilho",
        "description": "Dispara um dos gatilhos do CRM (ex.: \"pago\", \"recusado\", \"link_gerado\") na conversa do cliente: as etiquetas ligadas a ele são aplicadas e o funil anda. Ex.: o ERP avisa que o pedido foi pago.\n\n**Permissão da chave:** `etiquetas:aplicar` (Aplicar e remover etiquetas).",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "gatilho",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O gatilho (pago, recusado, link_gerado…)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "etiquetas:aplicar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/mensagens": {
      "post": {
        "operationId": "post_mensagens",
        "tags": [
          "Mensagens"
        ],
        "summary": "Enviar mensagem (WhatsApp)",
        "description": "Manda UMA coisa para um cliente (\"para\": \"ext:…\") ou telefone: \"texto\"; \"midia\" ({ tipo, url https OU arquivo de POST /v1/mensagens/midias, legenda, nomeArquivo, voz: true para mensagem de voz }); \"template\" (o aprovado na Meta — com variáveis e, se o template tiver, cabeçalho, botões, carrossel, cupom ou código de acesso); \"interativo\" ({ tipo: botoes, lista, link, carrossel, pedirLocalizacao, catalogo, produtos ou pix, e os campos do tipo — os mesmos das rotas de cada um em /v1/conversas/{id}/…}); \"localizacao\"; \"contatos\"; \"figurinha\"; ou \"enquete\" (só QR code). Número oficial fora da janela de 24 h só aceita template. Respeita a lista \"não perturbe\" e tem teto próprio (padrão 30/min e 1.000/dia por empresa) — para volume, use campanhas. Use Idempotency-Key: pedido repetido não manda de novo.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "para": "ext:ERP-1042",
                "texto": "Olá, Maria! Seu pedido saiu para entrega."
              }
            }
          }
        }
      }
    },
    "/mensagens/{id}": {
      "get": {
        "operationId": "get_mensagens_id",
        "tags": [
          "Mensagens"
        ],
        "summary": "Situação de uma mensagem",
        "description": "enviada, entregue, lida ou falhou.\n\n**Permissão da chave:** `mensagens:ler` (Ver situação de mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da mensagem"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:ler"
      },
      "patch": {
        "operationId": "patch_mensagens_id",
        "tags": [
          "Mensagens"
        ],
        "summary": "Editar mensagem enviada",
        "description": "Troca o \"texto\" de uma mensagem de texto que a empresa mandou, até 15 minutos depois de enviada — o cliente vê \"editada\". Só pelo WhatsApp conectado por QR code: a API oficial da Meta, o Instagram e o Messenger não oferecem.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da mensagem"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Correção: a entrega é amanhã, às 10h."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_mensagens_id",
        "tags": [
          "Mensagens"
        ],
        "summary": "Apagar para todos",
        "description": "O \"apagar para todos\" do WhatsApp numa mensagem que a empresa mandou: some do celular do cliente e fica marcada como apagada no CRM. Só pelo WhatsApp conectado por QR code, e dentro do prazo que o WhatsApp dá. Repetir não dá erro (\"mudou\": false).\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da mensagem"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar"
      }
    },
    "/mensagens/{id}/reacao": {
      "post": {
        "operationId": "post_mensagens_id_reacao",
        "tags": [
          "Mensagens"
        ],
        "summary": "Reagir a uma mensagem",
        "description": "Põe um \"emoji\" numa mensagem da conversa (do cliente ou da empresa), como o toque longo no WhatsApp. \"emoji\" vazio tira a reação. WhatsApp oficial e QR code.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da mensagem"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "emoji": "👍"
              }
            }
          }
        }
      }
    },
    "/mensagens/midias": {
      "post": {
        "operationId": "post_mensagens_midias",
        "tags": [
          "Mensagens"
        ],
        "summary": "Subir um arquivo para enviar",
        "description": "O arquivo CRU no corpo, com o Content-Type dele: JPEG, PNG, WEBP (figurinha), MP4, 3GP, OGG, MP3, M4A, AAC, AMR, PDF, DOC/DOCX, XLS/XLSX, PPT/PPTX, TXT, CSV ou ZIP, até 16 MB. \"?nome=relatorio.pdf\" sugere o nome do documento. Devolve o \"midia\" — vale 7 dias e só para esta empresa — para usar em \"midia\": { \"arquivo\": \"<midia>\" } em qualquer envio, ou em \"figurinha\".\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "video/mp4": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "video/quicktime": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/jpeg": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/webp": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "example": {
                "url": "https://meusite.com.br/video.mp4"
              }
            }
          }
        }
      }
    },
    "/numeros/{telefone}": {
      "get": {
        "operationId": "get_numeros_telefone",
        "tags": [
          "Mensagens"
        ],
        "summary": "Este número tem WhatsApp?",
        "description": "\"temWhatsapp\": true, false ou null (não deu para saber agora — tente depois). A pergunta é feita por uma conexão por QR code (\"canal\" escolhe qual): a API oficial da Meta não oferece esta consulta. Cada consulta gasta a reputação do chip, por isso o teto é de 10 por minuto e 300 por dia por empresa, e a resposta pode levar alguns segundos.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "telefone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O telefone"
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "A conexão por QR code que faz o pedido (veja GET /v1/canais); sem ele, a primeira conectada"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar"
      }
    },
    "/templates": {
      "get": {
        "operationId": "get_templates",
        "tags": [
          "Disparos"
        ],
        "summary": "Templates aprovados",
        "description": "Os templates aprovados de cada número oficial, com o texto e as variáveis.\n\n**Permissão da chave:** `campanhas:ler` (Ler campanhas e templates).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:ler"
      }
    },
    "/campanhas/previa": {
      "post": {
        "operationId": "post_campanhas_previa",
        "tags": [
          "Disparos"
        ],
        "summary": "Contar o público",
        "description": "Quantos clientes o filtro alcança, antes de criar a campanha.\n\n**Permissão da chave:** `campanhas:ler` (Ler campanhas e templates).\n\n**Plano:** depende do módulo `campanhas`.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:ler",
        "x-modulo": "campanhas",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "publico": {
                  "etapa": "novos",
                  "etiquetas": [
                    "Cliente VIP"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/campanhas/midias": {
      "post": {
        "operationId": "post_campanhas_midias",
        "tags": [
          "Disparos"
        ],
        "summary": "Enviar foto ou vídeo da campanha",
        "description": "Corpo cru: vídeo MP4 (até 16 MB) ou foto JPEG/PNG/WEBP (até 8 MB; vira JPEG com o lado maior em até 1600 px). Ou JSON { \"url\": \"https://…\" } — o CRM baixa uma vez. Devolve o \"midia\" para POST /v1/campanhas.\n\n**Permissão da chave:** `campanhas:gerenciar` (Criar e controlar campanhas).\n\n**Plano:** depende do módulo `campanhas`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:gerenciar",
        "x-modulo": "campanhas",
        "requestBody": {
          "required": true,
          "content": {
            "video/mp4": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "video/quicktime": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/jpeg": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/webp": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "example": {
                "url": "https://meusite.com.br/video.mp4"
              }
            }
          }
        }
      }
    },
    "/campanhas": {
      "post": {
        "operationId": "post_campanhas",
        "tags": [
          "Disparos"
        ],
        "summary": "Criar campanha (disparo em massa)",
        "description": "Pelo mesmo motor das campanhas da tela (anti-banimento, disjuntor, intervalo, teto diário). Público por filtro (\"publico\") ou lista junto (\"clientes\", até 1.000 — cada um é criado ou atualizado). \"canal\": \"oficial\" exige template; \"qr\" usa \"mensagem\" (aceita {nome}). \"midia\": o nome devolvido por POST /v1/campanhas/midias, ou { \"url\": \"https://…\" } — no QR vai com a mensagem de legenda e sem botões; no oficial, vai no cabeçalho do template (que precisa ter cabeçalho de imagem ou vídeo). \"iniciar\": true já começa; para começar depois, \"iniciarEm\" (ISO com fuso) ou \"dia\"+\"hora\" (horário de São Paulo). Por QR, cada número manda no máximo uma mensagem de campanha a cada 45 a 90 s. BOTÕES: por QR, \"botoes\" (até 3 — { id, texto } de resposta, { texto, url }, { texto, copiar } ou { texto, telefone }) ou \"lista\" ({ botao, opcoes: [{ id, titulo, descricao }] }, até 10), sem mídia junto; o toque volta como mensagem, com o \"id\". No oficial os botões são os do template aprovado, e \"template.botoes\" manda os valores dos que têm parâmetro: [{ tipo: link (o fim do link dinâmico) | copiar (o cupom) | resposta (o payload), indice (a posição do botão no template, a partir de 0), valor }] — \"{{1}}\" no valor vira a primeira variável daquela pessoa.\n\n**Permissão da chave:** `campanhas:gerenciar` (Criar e controlar campanhas).\n\n**Plano:** depende do módulo `campanhas`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:gerenciar",
        "x-modulo": "campanhas",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Aviso de entrega",
                "canal": "qr",
                "mensagem": "Oi {nome}, seu pedido chegou! Quer agendar a entrega?",
                "botoes": [
                  {
                    "id": "agendar",
                    "texto": "Agendar"
                  },
                  {
                    "id": "depois",
                    "texto": "Depois"
                  }
                ],
                "clientes": [
                  {
                    "nome": "Maria",
                    "telefone": "62999998888",
                    "codigoExterno": "ERP-1042"
                  }
                ],
                "iniciarEm": "2026-10-12T14:00:00-03:00"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "get_campanhas",
        "tags": [
          "Disparos"
        ],
        "summary": "Listar campanhas",
        "description": "As mais recentes primeiro.\n\n**Permissão da chave:** `campanhas:ler` (Ler campanhas e templates).\n\n**Plano:** depende do módulo `campanhas`.",
        "parameters": [
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 100; padrão 20)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:ler",
        "x-modulo": "campanhas"
      }
    },
    "/campanhas/{id}": {
      "get": {
        "operationId": "get_campanhas_id",
        "tags": [
          "Disparos"
        ],
        "summary": "Progresso da campanha",
        "description": "Status, total, enviados, falhas e os últimos envios.\n\n**Permissão da chave:** `campanhas:ler` (Ler campanhas e templates).\n\n**Plano:** depende do módulo `campanhas`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da campanha"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:ler",
        "x-modulo": "campanhas"
      }
    },
    "/campanhas/{id}/{acao}": {
      "post": {
        "operationId": "post_campanhas_id_acao",
        "tags": [
          "Disparos"
        ],
        "summary": "Iniciar, pausar, retomar, cancelar ou desagendar",
        "description": ":acao é iniciar, pausar, retomar, cancelar ou desagendar. Numa campanha agendada, \"iniciar\" começa agora e \"desagendar\" a devolve a rascunho, sem hora.\n\n**Permissão da chave:** `campanhas:gerenciar` (Criar e controlar campanhas).\n\n**Plano:** depende do módulo `campanhas`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da campanha"
          },
          {
            "name": "acao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "iniciar, pausar, retomar ou cancelar"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "campanhas:gerenciar",
        "x-modulo": "campanhas",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/publicacoes/destinos": {
      "get": {
        "operationId": "get_publicacoes_destinos",
        "tags": [
          "Publicações"
        ],
        "summary": "Onde dá para publicar",
        "description": "As contas do Instagram e as conexões do WhatsApp (Status), com os formatos de cada uma e a cota do Instagram.\n\n**Permissão da chave:** `publicacoes:ler` (Ler publicações).\n\n**Plano:** depende do módulo `publicacoes`.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:ler",
        "x-modulo": "publicacoes"
      }
    },
    "/midias": {
      "post": {
        "operationId": "post_midias",
        "tags": [
          "Publicações"
        ],
        "summary": "Subir foto ou vídeo",
        "description": "Mande o ARQUIVO no corpo (Content-Type video/mp4, video/quicktime, image/jpeg, image/png ou image/webp; vídeo até 100 MB, foto até 8 MB; para o Status do WhatsApp, vídeo só MP4 até 8 MB) ou JSON { \"url\": \"https://…\" } para o CRM baixar. Devolve \"midia\", que vai no POST /v1/publicacoes.\n\n**Permissão da chave:** `publicacoes:publicar` (Publicar no Instagram e no Status).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:publicar",
        "x-modulo": "publicacoes",
        "requestBody": {
          "required": true,
          "content": {
            "video/mp4": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "video/quicktime": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/jpeg": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/webp": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "example": {
                "url": "https://meusite.com.br/video.mp4"
              }
            }
          }
        }
      }
    },
    "/publicacoes": {
      "post": {
        "operationId": "post_publicacoes",
        "tags": [
          "Publicações"
        ],
        "summary": "Publicar agora ou agendar",
        "description": "Instagram: IMAGE, CAROUSEL (2 a 10 fotos em \"midias\"), STORIES ou REELS. Status do WhatsApp: texto, foto ou video (vídeo só MP4 até 8 MB). Sem \"quando\", publica agora; com \"quando\" (ISO com fuso) ou \"dia\"+\"hora\" (horário de São Paulo), agenda. Passa pelo mesmo motor do /publicacoes. \"legenda\" é o texto do post (foto, carrossel e Reels; até 2.200 caracteres). \"comentario\" é o PRIMEIRO COMENTÁRIO, que sai logo depois do post; fixá-lo no topo só pelo aplicativo do Instagram (a API da Meta não fixa). O Story não aceita legenda nem comentário: texto de Story tem de estar escrito na própria imagem.\n\n**Permissão da chave:** `publicacoes:publicar` (Publicar no Instagram e no Status).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:publicar",
        "x-modulo": "publicacoes",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "destino": "instagram",
                "canal": 996001,
                "formato": "REELS",
                "midia": "0123456789abcdef0123456789abcdef.mp4",
                "legenda": "Novidade da semana!",
                "comentario": "Comente EU QUERO que te mando o link no Direct",
                "quando": "2026-09-26T18:00:00-03:00"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "get_publicacoes",
        "tags": [
          "Publicações"
        ],
        "summary": "Listar publicações",
        "description": "As mais recentes primeiro; filtro \"status\" (agendada, publicada, falhou…).\n\n**Permissão da chave:** `publicacoes:ler` (Ler publicações).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "agendada, publicando, publicada, falhou…"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 100; padrão 20)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:ler",
        "x-modulo": "publicacoes"
      }
    },
    "/publicacoes/{id}/reagendar": {
      "post": {
        "operationId": "post_publicacoes_id_reagendar",
        "tags": [
          "Publicações"
        ],
        "summary": "Agendar ou reagendar publicação",
        "description": "Publicação AGENDADA: muda a data e a hora. RASCUNHO (por exemplo, o que sai de \"duplicar\"): agenda para valer. \"quando\" (ISO com fuso) ou \"dia\"+\"hora\" (horário de São Paulo).\n\n**Permissão da chave:** `publicacoes:publicar` (Publicar no Instagram e no Status).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da publicação"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:publicar",
        "x-modulo": "publicacoes",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "quando": "2026-09-28T10:00:00-03:00"
              }
            }
          }
        }
      }
    },
    "/publicacoes/{id}/tentar-de-novo": {
      "post": {
        "operationId": "post_publicacoes_id_tentar_de_novo",
        "tags": [
          "Publicações"
        ],
        "summary": "Tentar de novo a publicação que falhou",
        "description": "Só para publicação com status \"falhou\": ela volta para a fila e sai de novo.\n\n**Permissão da chave:** `publicacoes:publicar` (Publicar no Instagram e no Status).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da publicação"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:publicar",
        "x-modulo": "publicacoes",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/publicacoes/{id}/duplicar": {
      "post": {
        "operationId": "post_publicacoes_id_duplicar",
        "tags": [
          "Publicações"
        ],
        "summary": "Duplicar publicação",
        "description": "Cria um RASCUNHO igual (formato, legenda e mídia), na mesma conta ou em outra (\"canal\"). O rascunho não sai sozinho: agende por POST /v1/publicacoes/{id}/reagendar.\n\n**Permissão da chave:** `publicacoes:publicar` (Publicar no Instagram e no Status).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da publicação"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:publicar",
        "x-modulo": "publicacoes",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "canal": 996001
              }
            }
          }
        }
      }
    },
    "/publicacoes/{id}": {
      "get": {
        "operationId": "get_publicacoes_id",
        "tags": [
          "Publicações"
        ],
        "summary": "Situação da publicação",
        "description": "agendada, publicando, publicada (com o link) ou falhou (com o motivo).\n\n**Permissão da chave:** `publicacoes:ler` (Ler publicações).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da publicação"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:ler",
        "x-modulo": "publicacoes"
      },
      "delete": {
        "operationId": "delete_publicacoes_id",
        "tags": [
          "Publicações"
        ],
        "summary": "Cancelar publicação",
        "description": "Cancela uma publicação agendada que ainda não saiu.\n\n**Permissão da chave:** `publicacoes:publicar` (Publicar no Instagram e no Status).\n\n**Plano:** depende do módulo `publicacoes`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da publicação"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "publicacoes:publicar",
        "x-modulo": "publicacoes"
      }
    },
    "/conversas": {
      "get": {
        "operationId": "get_conversas",
        "tags": [
          "Atendimento"
        ],
        "summary": "Listar conversas",
        "description": "As conversas que a pessoa dona da chave enxerga no Atendimento (fila, equipe e carteira dela). Filtros: status (aguardando, atendendo, bot, fechado ou abertas), canal, conexao, fila, atendente (id, \"eu\" ou \"nenhum\"), cliente (ext:, tel:, id), telefone, grupo (true/false), atualizadaDesde (ISO). \"ordem\": recentes (padrão) ou antigas — com \"antigas\" + atualizadaDesde dá para sincronizar. Paginação por \"cursor\"; \"limite\" até 100.\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "aguardando",
                "atendendo",
                "bot",
                "fechado",
                "abertas"
              ]
            },
            "description": "Situação da conversa"
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Tipo do canal (whatsapp_official, whatsapp, instagram_official, messenger, webchat)"
          },
          {
            "name": "conexao",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "O número da conexão (veja GET /v1/canais)"
          },
          {
            "name": "fila",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Id da fila (veja GET /v1/filas)"
          },
          {
            "name": "atendente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Id do atendente, \"eu\" (quem é dono da chave) ou \"nenhum\""
          },
          {
            "name": "grupo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true só grupos; false sem grupos"
          },
          {
            "name": "cliente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone> ou o id do CRM"
          },
          {
            "name": "telefone",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Telefone do contato, com DDD"
          },
          {
            "name": "atualizadaDesde",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Só as atualizadas a partir deste instante (ISO)"
          },
          {
            "name": "ordem",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "recentes",
                "antigas"
              ]
            },
            "description": "recentes (padrão) ou antigas"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 100; padrão 50)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior (paginação)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      }
    },
    "/conversas/{id}": {
      "get": {
        "operationId": "get_conversas_id",
        "tags": [
          "Atendimento"
        ],
        "summary": "Abrir uma conversa",
        "description": "Situação, canal, contato, fila, atendente, IA pausada ou não, protocolo, etiquetas, quantas não lidas, a última mensagem e as mensagens agendadas.\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      },
      "patch": {
        "operationId": "patch_conversas_id",
        "tags": [
          "Atendimento"
        ],
        "summary": "Prioridade e leitura",
        "description": "\"prioridade\": baixa, normal, alta ou urgente. \"lida\": true marca como lida; false, como não lida.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "prioridade": "alta"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/mensagens": {
      "get": {
        "operationId": "get_conversas_id_mensagens",
        "tags": [
          "Atendimento"
        ],
        "summary": "Histórico de mensagens",
        "description": "Mais recentes primeiro (ou \"ordem=antigas\"). \"desde\" (ISO) corta o começo; \"internas=false\" esconde as notas internas. Mensagem com arquivo traz o endereço para baixar (GET /v1/mensagens/{id}/midia). Paginação por \"cursor\"; \"limite\" até 100.\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "desde",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Só as mensagens a partir deste instante (ISO)"
          },
          {
            "name": "internas",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "false esconde as notas internas"
          },
          {
            "name": "ordem",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "recentes",
                "antigas"
              ]
            },
            "description": "recentes (padrão) ou antigas"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 100; padrão 50)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior (paginação)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      },
      "post": {
        "operationId": "post_conversas_id_mensagens",
        "tags": [
          "Atendimento"
        ],
        "summary": "Responder na conversa (qualquer canal)",
        "description": "Manda UMA coisa pelo canal da conversa (WhatsApp oficial ou QR, Instagram, Messenger e webchat), com o corpo de POST /v1/mensagens: \"texto\", \"midia\" ({ tipo: imagem|video|audio|documento, url https OU arquivo de POST /v1/mensagens/midias, legenda, nomeArquivo, voz }), \"interativo\", \"localizacao\", \"contatos\", \"figurinha\" ou \"enquete\". Não assume a conversa nem pausa a IA — para isso, /atribuir. Número oficial fora da janela de 24 h só aceita template (POST /v1/mensagens). Respeita o \"não perturbe\" e divide o teto de envio com POST /v1/mensagens.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Seu pedido 1042 foi despachado hoje."
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/botoes": {
      "post": {
        "operationId": "post_conversas_id_botoes",
        "tags": [
          "Atendimento"
        ],
        "summary": "Responder com botões",
        "description": "Texto com até 3 botões. De resposta ({ \"id\", \"texto\" até 20 letras }): o toque volta como mensagem, com o \"id\" (aviso mensagem.recebida, campo \"resposta\"). Pelo QR code também de link ({ texto, url }), de copiar ({ texto, copiar }) e de ligar ({ texto, telefone }); no Instagram e no Messenger, de resposta ou de link. \"cabecalho\" (texto; no número oficial também { tipo: imagem|video|documento, url }) e \"rodape\" são opcionais. WhatsApp oficial e QR, Instagram e Messenger.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Posso confirmar seu pedido?",
                "botoes": [
                  {
                    "id": "sim",
                    "texto": "Sim, confirmar"
                  },
                  {
                    "id": "nao",
                    "texto": "Ainda não"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/lista": {
      "post": {
        "operationId": "post_conversas_id_lista",
        "tags": [
          "Atendimento"
        ],
        "summary": "Responder com lista de opções",
        "description": "Texto com um botão (\"botao\", até 20 letras) que abre uma lista de até 10 opções ({ \"id\", \"titulo\" até 24 letras, \"descricao\" até 72 }), numa seção só (\"opcoes\") ou em várias (\"secoes\": [{ titulo, opcoes }]). O toque volta como mensagem, com o \"id\". WhatsApp oficial e QR; no Instagram e no Messenger vira respostas rápidas (título até 20 letras).\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Escolha o horário:",
                "botao": "Ver horários",
                "opcoes": [
                  {
                    "id": "manha",
                    "titulo": "Manhã",
                    "descricao": "9h às 12h"
                  },
                  {
                    "id": "tarde",
                    "titulo": "Tarde"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/link": {
      "post": {
        "operationId": "post_conversas_id_link",
        "tags": [
          "Atendimento"
        ],
        "summary": "Responder com botão de link",
        "description": "Texto com UM botão que abre um endereço (\"botao\" até 20 letras, \"url\" https). O toque NÃO volta para o CRM: abre o site no aparelho do cliente. \"cabecalho\" e \"rodape\" opcionais. WhatsApp oficial e QR, Instagram e Messenger.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Seu boleto está pronto.",
                "botao": "Abrir boleto",
                "url": "https://minhaloja.com.br/boleto/1042"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/carrossel": {
      "post": {
        "operationId": "post_conversas_id_carrossel",
        "tags": [
          "Atendimento"
        ],
        "summary": "Responder com carrossel",
        "description": "Cartões que o cliente desliza, cada um com \"imagem\" (https), \"texto\" e botões — de resposta ({ id, texto }) ou um de link ({ texto, url }). Número oficial: de 2 a 10 cartões, todos com os MESMOS botões (mesmo tipo e quantidade), texto do cartão até 160 letras (\"video\" no lugar de \"imagem\" também vale). Instagram e Messenger: de 1 a 10, cada um com \"titulo\" (até 80) e até 3 botões. QR code: de 2 a 10, 1 ou 2 botões; a imagem é baixada e mandada junto, e o desenho depende do aparelho do cliente.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Veja as opções da semana:",
                "cartoes": [
                  {
                    "imagem": "https://minhaloja.com.br/p/1.jpg",
                    "texto": "Bolsa Aurora — R$ 189",
                    "botoes": [
                      {
                        "id": "quero_1",
                        "texto": "Quero esta"
                      }
                    ]
                  },
                  {
                    "imagem": "https://minhaloja.com.br/p/2.jpg",
                    "texto": "Bolsa Lua — R$ 149",
                    "botoes": [
                      {
                        "id": "quero_2",
                        "texto": "Quero esta"
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/respostas-rapidas": {
      "post": {
        "operationId": "post_conversas_id_respostas_rapidas",
        "tags": [
          "Atendimento"
        ],
        "summary": "Responder com respostas rápidas",
        "description": "Instagram e Messenger: texto com até 13 respostas que aparecem sobre o teclado ({ \"id\", \"texto\" até 20 letras }) e somem depois do toque. O toque volta como mensagem, com o \"id\". No WhatsApp, use botões ou lista.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Qual tamanho você usa?",
                "opcoes": [
                  {
                    "id": "p",
                    "texto": "P"
                  },
                  {
                    "id": "m",
                    "texto": "M"
                  },
                  {
                    "id": "g",
                    "texto": "G"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/localizacao": {
      "post": {
        "operationId": "post_conversas_id_localizacao",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mandar uma localização",
        "description": "Um ponto no mapa (\"latitude\" e \"longitude\"; \"nome\" e \"endereco\" opcionais) que abre a rota no aparelho do cliente. WhatsApp oficial e QR code.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "latitude": -16.6869,
                "longitude": -49.2648,
                "nome": "Loja Centro",
                "endereco": "Av. Goiás, 1000 — Goiânia"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/pedir-localizacao": {
      "post": {
        "operationId": "post_conversas_id_pedir_localizacao",
        "tags": [
          "Atendimento"
        ],
        "summary": "Pedir a localização do cliente",
        "description": "Texto com o botão \"Enviar localização\": o cliente toca e a localização dele volta como mensagem. Só no WhatsApp oficial (regra da Meta).\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Para calcular o frete, mande sua localização tocando no botão abaixo."
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/contato": {
      "post": {
        "operationId": "post_conversas_id_contato",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mandar cartão de contato",
        "description": "Até 10 cartões de contato (\"contatos\": [{ nome, telefone com DDD, empresa, email }]) — o cliente salva ou chama direto. WhatsApp oficial e QR code.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "contatos": [
                  {
                    "nome": "Financeiro Loja Centro",
                    "telefone": "62999990000",
                    "empresa": "Loja Centro"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/figurinha": {
      "post": {
        "operationId": "post_conversas_id_figurinha",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mandar figurinha",
        "description": "Figurinha WEBP 512×512: \"url\" (https) ou \"arquivo\" (o \"midia\" de POST /v1/mensagens/midias); \"animada\": true para a animada. WhatsApp oficial e QR code.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://minhaloja.com.br/figurinhas/obrigado.webp"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/enquete": {
      "post": {
        "operationId": "post_conversas_id_enquete",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mandar enquete",
        "description": "Enquete do WhatsApp: \"pergunta\" e de 2 a 12 \"opcoes\" (textos); \"variasEscolhas\": true deixa marcar mais de uma. Cada voto volta como mensagem com as opções marcadas (aviso mensagem.recebida, \"resposta.formato\": \"enquete\"). Só pelo WhatsApp conectado por QR code — a API oficial da Meta não tem enquete.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "pergunta": "Qual horário fica melhor?",
                "opcoes": [
                  "Manhã",
                  "Tarde",
                  "Noite"
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/catalogo": {
      "post": {
        "operationId": "post_conversas_id_catalogo",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mandar o catálogo",
        "description": "O catálogo da loja dentro do WhatsApp (\"texto\"; \"produtoDaCapa\" é o código do produto que vira a miniatura; \"rodape\" opcional). Só no número oficial com catálogo ligado na conta da Meta.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Veja nossos produtos e peça por aqui mesmo."
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/produtos": {
      "post": {
        "operationId": "post_conversas_id_produtos",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mandar produtos do catálogo",
        "description": "Um produto (\"catalogo\" + \"produto\", os códigos do catálogo da Meta) ou uma vitrine com até 30 (\"catalogo\", \"titulo\", \"texto\", \"secoes\": [{ titulo, produtos: [códigos] }], até 10 seções). Só no número oficial.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "catalogo": "<id do catálogo na Meta>",
                "titulo": "Novidades",
                "texto": "Separei estas para você:",
                "secoes": [
                  {
                    "titulo": "Bolsas",
                    "produtos": [
                      "BOLSA-AURORA",
                      "BOLSA-LUA"
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/pix": {
      "post": {
        "operationId": "post_conversas_id_pix",
        "tags": [
          "Atendimento"
        ],
        "summary": "Cobrar por Pix",
        "description": "Pedido com Pix: \"texto\", \"referencia\" (o código do pedido), \"itens\" [{ nome, valor em reais, quantidade }], \"frete\", \"desconto\" e o Pix — \"codigo\" (o copia e cola), \"chave\", \"tipoChave\" (CPF, CNPJ, EMAIL, PHONE ou EVP) e \"recebedor\". No número oficial vai a mensagem de pedido da Meta, com \"Revisar e pagar\"; no QR code, o texto com o total e o botão \"Copiar código Pix\". O CRM não confirma o pagamento: isso vem do seu banco.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Seu pedido 1042",
                "referencia": "PED-1042",
                "itens": [
                  {
                    "nome": "Bolsa Aurora",
                    "valor": 189.9,
                    "quantidade": 1
                  }
                ],
                "frete": 15,
                "codigo": "00020126…6304ABCD",
                "chave": "12345678000199",
                "tipoChave": "CNPJ",
                "recebedor": "Loja Centro"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/lida": {
      "post": {
        "operationId": "post_conversas_id_lida",
        "tags": [
          "Atendimento"
        ],
        "summary": "Marcar como lida (visto)",
        "description": "Manda o \"visto\" ao cliente (os dois tiques azuis no WhatsApp; \"visto\" no Instagram e no Messenger) e marca a conversa como lida no CRM.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/digitando": {
      "post": {
        "operationId": "post_conversas_id_digitando",
        "tags": [
          "Atendimento"
        ],
        "summary": "Mostrar digitando",
        "description": "\"estado\": digitando (padrão), gravando (só QR code: \"gravando áudio…\") ou parou. Some sozinho em alguns segundos ou quando a resposta sai. No número oficial, regra da Meta: ele vai junto com o \"visto\" da última mensagem do cliente.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "estado": "digitando"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/atribuir": {
      "post": {
        "operationId": "post_conversas_id_atribuir",
        "tags": [
          "Atendimento"
        ],
        "summary": "Atribuir a um atendente",
        "description": "\"atendente\": id da pessoa (GET /v1/atendentes) ou \"eu\". A conversa fica \"atendendo\" e a IA pausa, como no botão \"Aceitar\". Se outra pessoa assumiu primeiro, 409.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "atendente": "eu"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/devolver-para-ia": {
      "post": {
        "operationId": "post_conversas_id_devolver_para_ia",
        "tags": [
          "Atendimento"
        ],
        "summary": "Devolver para a IA",
        "description": "Tira o atendente, volta a conversa para \"aguardando\" e religa a IA nela.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/transferir": {
      "post": {
        "operationId": "post_conversas_id_transferir",
        "tags": [
          "Atendimento"
        ],
        "summary": "Transferir",
        "description": "Para uma \"fila\" (GET /v1/filas) e/ou um \"atendente\". \"nota\" vira nota interna na conversa. A IA pausa, como na tela.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "fila": "id-da-fila-financeiro",
                "nota": "Cliente quer segunda via do boleto"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/ia": {
      "post": {
        "operationId": "post_conversas_id_ia",
        "tags": [
          "Atendimento"
        ],
        "summary": "Pausar ou religar a IA",
        "description": "\"pausada\": true para a IA parar de responder nesta conversa; false para ela voltar. O pedido diz o estado final — repetir não desfaz.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "pausada": true
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/encerrar": {
      "post": {
        "operationId": "post_conversas_id_encerrar",
        "tags": [
          "Atendimento"
        ],
        "summary": "Encerrar atendimento",
        "description": "Fecha a conversa e o ticket, gera o protocolo e dispara a pesquisa de satisfação se estiver configurada (\"enviarPesquisa\": true força). \"despedida\" é mandada ao cliente antes de fechar. Já encerrada: 409.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "despedida": "Obrigado pelo contato! Qualquer coisa, é só chamar."
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/reabrir": {
      "post": {
        "operationId": "post_conversas_id_reabrir",
        "tags": [
          "Atendimento"
        ],
        "summary": "Reabrir",
        "description": "Volta um atendimento encerrado para \"aguardando\", com ticket novo.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/notas": {
      "post": {
        "operationId": "post_conversas_id_notas",
        "tags": [
          "Atendimento"
        ],
        "summary": "Nota interna",
        "description": "Deixa uma nota que só a equipe vê — o cliente não recebe.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Pagamento confirmado no ERP em 25/09."
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/adiar": {
      "post": {
        "operationId": "post_conversas_id_adiar",
        "tags": [
          "Atendimento"
        ],
        "summary": "Adiar",
        "description": "Tira a conversa da fila até \"ate\" (ISO COM fuso) — ela volta sozinha. \"motivo\" vira nota interna.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "ate": "2026-09-26T09:00:00-03:00",
                "motivo": "Cliente pediu retorno amanhã"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_conversas_id_adiar",
        "tags": [
          "Atendimento"
        ],
        "summary": "Tirar o adiamento",
        "description": "A conversa volta para a fila agora.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar"
      }
    },
    "/conversas/{id}/pesquisa": {
      "post": {
        "operationId": "post_conversas_id_pesquisa",
        "tags": [
          "Atendimento"
        ],
        "summary": "Enviar pesquisa de satisfação",
        "description": "Manda a pesquisa (nota de 1 a 5) ao cliente agora.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/mensagens-agendadas": {
      "post": {
        "operationId": "post_conversas_id_mensagens_agendadas",
        "tags": [
          "Atendimento"
        ],
        "summary": "Agendar mensagem",
        "description": "\"tipo\": mensagem (sai para o cliente no horário) ou lembrete (aviso interno para a equipe). \"quando\": ISO COM fuso, de 30 segundos a 90 dias à frente.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Oi! Passando para lembrar do vencimento amanhã.",
                "quando": "2026-09-29T10:00:00-03:00",
                "tipo": "mensagem"
              }
            }
          }
        }
      }
    },
    "/conversas/{id}/mensagens-agendadas/{agendada}": {
      "delete": {
        "operationId": "delete_conversas_id_mensagens_agendadas_agendada",
        "tags": [
          "Atendimento"
        ],
        "summary": "Cancelar mensagem agendada",
        "description": "Só a que ainda não saiu. Já processada: 409.\n\n**Permissão da chave:** `conversas:gerenciar` (Conduzir o atendimento).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "agendada",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A mensagem agendada (id, em \"mensagensAgendadas\" de GET /v1/conversas/{id})"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:gerenciar"
      }
    },
    "/mensagens/{id}/midia": {
      "get": {
        "operationId": "get_mensagens_id_midia",
        "tags": [
          "Atendimento"
        ],
        "summary": "Baixar o arquivo de uma mensagem",
        "description": "Devolve o arquivo (foto, áudio, vídeo, documento) guardado no CRM, com o Content-Type dele.\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da mensagem"
          }
        ],
        "responses": {
          "200": {
            "description": "O arquivo, com o Content-Type dele",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      }
    },
    "/grupos": {
      "get": {
        "operationId": "get_grupos",
        "tags": [
          "Grupos"
        ],
        "summary": "Listar grupos",
        "description": "Os grupos de WhatsApp de que o número participa: id, nome, descrição, quantas pessoas, se a empresa é administradora, quem pode mandar e editar, e a \"conversaId\" quando o grupo já tem conversa no CRM. Só pela conexão por QR code (\"canal\" escolhe qual).\n\n**Permissão da chave:** `grupos:ler` (Ver grupos de WhatsApp).",
        "parameters": [
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "A conexão por QR code que faz o pedido (veja GET /v1/canais); sem ele, a primeira conectada"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:ler"
      },
      "post": {
        "operationId": "post_grupos",
        "tags": [
          "Grupos"
        ],
        "summary": "Criar grupo",
        "description": "\"nome\" (até 25 letras, limite do WhatsApp) e \"participantes\" (telefones com DDD, até 50). Quem está no \"não perturbe\" não entra (volta em \"recusados\"), e o WhatsApp pode recusar quem não deixa ser posto em grupo (volta com \"ok\": false). Até 10 grupos novos por dia: criar grupo em série é o padrão que o WhatsApp bane.\n\n**Permissão da chave:** `grupos:gerenciar` (Administrar grupos de WhatsApp).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Turma de outubro",
                "participantes": [
                  "62999990000",
                  "62988880000"
                ]
              }
            }
          }
        }
      }
    },
    "/grupos/{id}": {
      "get": {
        "operationId": "get_grupos_id",
        "tags": [
          "Grupos"
        ],
        "summary": "Ver um grupo",
        "description": "O grupo com as \"pessoas\" (\"id\" no grupo, telefone quando o WhatsApp informa, administrador ou não) e o telefone do dono.\n\n**Permissão da chave:** `grupos:ler` (Ver grupos de WhatsApp).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "A conexão por QR code que faz o pedido (veja GET /v1/canais); sem ele, a primeira conectada"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:ler"
      },
      "patch": {
        "operationId": "patch_grupos_id",
        "tags": [
          "Grupos"
        ],
        "summary": "Editar grupo",
        "description": "Muda só o que vier: \"nome\" (até 25 letras), \"descricao\", \"soAdminsEnviam\" (só administradores mandam mensagem) e \"soAdminsEditam\" (só eles mudam nome e foto). A resposta diz, campo a campo, o que o WhatsApp aceitou (\"resultado\").\n\n**Permissão da chave:** `grupos:gerenciar` (Administrar grupos de WhatsApp).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Turma de outubro — 2026",
                "soAdminsEnviam": true
              }
            }
          }
        }
      }
    },
    "/grupos/{id}/convite": {
      "get": {
        "operationId": "get_grupos_id_convite",
        "tags": [
          "Grupos"
        ],
        "summary": "Link de convite",
        "description": "O link de convite atual do grupo. A empresa precisa ser administradora dele.\n\n**Permissão da chave:** `grupos:ler` (Ver grupos de WhatsApp).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "A conexão por QR code que faz o pedido (veja GET /v1/canais); sem ele, a primeira conectada"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:ler"
      },
      "post": {
        "operationId": "post_grupos_id_convite",
        "tags": [
          "Grupos"
        ],
        "summary": "Trocar o link de convite",
        "description": "Gera um link novo; o anterior para de funcionar.\n\n**Permissão da chave:** `grupos:gerenciar` (Administrar grupos de WhatsApp).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/grupos/{id}/mensagens": {
      "post": {
        "operationId": "post_grupos_id_mensagens",
        "tags": [
          "Grupos"
        ],
        "summary": "Mandar mensagem no grupo",
        "description": "O corpo de POST /v1/mensagens (\"texto\", \"midia\", \"enquete\", \"localizacao\", \"contatos\", \"figurinha\" ou \"interativo\" — botões, lista e link), no grupo. A conversa do grupo aparece no Atendimento, com a IA desligada como em todo grupo. Divide o teto de envio da API.\n\n**Permissão da chave:** `mensagens:enviar` (Enviar mensagens).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "mensagens:enviar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "texto": "Bom dia, pessoal! A loja abre às 9h hoje."
              }
            }
          }
        }
      }
    },
    "/grupos/{id}/participantes": {
      "post": {
        "operationId": "post_grupos_id_participantes",
        "tags": [
          "Grupos"
        ],
        "summary": "Pôr e tirar pessoas",
        "description": "\"acao\": adicionar, remover, promover (a administrador) ou rebaixar; \"participantes\": telefones com DDD, até 50 — para tirar ou promover quem só aparece sem telefone, use o \"id\" da pessoa em GET /v1/grupos/{id}. O resultado vem por pessoa; quem não deixa ser posto em grupo volta com \"ok\": false (e \"convidado\": true quando o WhatsApp mandou o convite a ela). A empresa precisa ser administradora do grupo; o \"não perturbe\" vale para adicionar.\n\n**Permissão da chave:** `grupos:gerenciar` (Administrar grupos de WhatsApp).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "acao": "adicionar",
                "participantes": [
                  "62999990000"
                ]
              }
            }
          }
        }
      }
    },
    "/grupos/{id}/sair": {
      "post": {
        "operationId": "post_grupos_id_sair",
        "tags": [
          "Grupos"
        ],
        "summary": "Sair do grupo",
        "description": "O número da empresa sai do grupo. A conversa e o histórico continuam no CRM.\n\n**Permissão da chave:** `grupos:gerenciar` (Administrar grupos de WhatsApp).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "grupos:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/filas": {
      "get": {
        "operationId": "get_filas",
        "tags": [
          "Atendimento"
        ],
        "summary": "Filas (departamentos)",
        "description": "As filas da empresa, com quem atende em cada uma — para transferir.\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      },
      "post": {
        "operationId": "post_filas",
        "tags": [
          "Administração"
        ],
        "summary": "Criar fila",
        "description": "\"nome\" é obrigatório. \"agenteIa\" (agente de mensagem desta empresa), \"fluxo\", \"horario\": { \"vinteQuatroHoras\", \"porDia\": { \"1\": { \"on\": true, \"faixas\": [[\"08:00\",\"18:00\"]] } } } (de \"0\", domingo, a \"6\", sábado) e \"atendentes\" (ids de usuário).\n\n**Permissão da chave:** `filas:gerenciar` (Configurar filas).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "filas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Cobrança",
                "iaLigada": false,
                "atendentes": [
                  "<id do usuário>"
                ]
              }
            }
          }
        }
      }
    },
    "/atendentes": {
      "get": {
        "operationId": "get_atendentes",
        "tags": [
          "Atendimento"
        ],
        "summary": "Atendentes",
        "description": "Quem está ativo na empresa, com o perfil e a presença (online, ausente, ocupado, offline).\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      }
    },
    "/agenda": {
      "get": {
        "operationId": "get_agenda",
        "tags": [
          "Agenda"
        ],
        "summary": "Compromissos",
        "description": "A partir de \"de\" (AAAA-MM-DD, dia de São Paulo; padrão hoje) por \"dias\" (até 45). Filtros: atendente (um ou vários ids, separados por vírgula) e status (marcado, confirmado, cancelado, realizado, faltou).\n\n**Permissão da chave:** `agenda:ler` (Ler a agenda).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "de",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Dia inicial AAAA-MM-DD, no horário de São Paulo (padrão: hoje)"
          },
          {
            "name": "dias",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Quantos dias a partir de \"de\" (até 45; padrão 7)"
          },
          {
            "name": "atendente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Id de um ou mais atendentes, separados por vírgula"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "marcado",
                "confirmado",
                "cancelado",
                "realizado",
                "faltou"
              ]
            },
            "description": "marcado, confirmado, cancelado, realizado ou faltou"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:ler",
        "x-modulo": "agenda"
      },
      "post": {
        "operationId": "post_agenda",
        "tags": [
          "Agenda"
        ],
        "summary": "Marcar compromisso",
        "description": "Pelas mesmas travas da tela e da IA: expediente, conflito e horário passado. Horário em \"data\" + \"hora\" (São Paulo) ou \"inicio\" (ISO com fuso). \"atendente\": id ou \"eu\". \"cliente\" (ext:, tel:, id) e \"conversa\" (id) são opcionais. Horário tomado: 409.\n\n**Permissão da chave:** `agenda:gerenciar` (Marcar e remarcar).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:gerenciar",
        "x-modulo": "agenda",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "atendente": "eu",
                "data": "2026-09-29",
                "hora": "14:00",
                "duracaoMin": 30,
                "titulo": "Assinatura do contrato",
                "cliente": "ext:ERP-1042"
              }
            }
          }
        }
      }
    },
    "/agenda/horarios-livres": {
      "get": {
        "operationId": "get_agenda_horarios_livres",
        "tags": [
          "Agenda"
        ],
        "summary": "Horários livres",
        "description": "As mesmas vagas que a IA ofereceria: dentro do expediente, sem conflito, com antecedência. Com \"dia\" (AAAA-MM-DD), todas as vagas daquele dia — e, sem nenhuma, \"proximoDia\". Sem \"dia\", a partir de \"de\" (padrão hoje) por \"dias\" (até 14), em dias inteiros até \"limite\" vagas (padrão 200); com \"temMais\": true, peça de novo com de=<continuarDe>, sem repetir horário. \"duracao\" em minutos, \"atendente\".\n\n**Permissão da chave:** `agenda:ler` (Ler a agenda).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "dia",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Um dia só, AAAA-MM-DD (horário de São Paulo): traz TODAS as vagas dele e, se não houver nenhuma, \"proximoDia\""
          },
          {
            "name": "de",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Sem \"dia\": o dia inicial AAAA-MM-DD, no horário de São Paulo (padrão: hoje)"
          },
          {
            "name": "dias",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Sem \"dia\": quantos dias à frente de \"de\" (até 14; padrão 7)"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Sem \"dia\": teto de vagas por resposta (até 1000; padrão 200). Vêm dias inteiros: o primeiro sempre completo, os seguintes enquanto couberem"
          },
          {
            "name": "duracao",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Duração em minutos (padrão 30)"
          },
          {
            "name": "atendente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Id de um ou mais atendentes, separados por vírgula"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:ler",
        "x-modulo": "agenda"
      }
    },
    "/agenda/equipe": {
      "get": {
        "operationId": "get_agenda_equipe",
        "tags": [
          "Agenda"
        ],
        "summary": "Equipe e expediente",
        "description": "Quem pode receber compromisso e o expediente de cada um (dia da semana 0 = domingo).\n\n**Permissão da chave:** `agenda:ler` (Ler a agenda).\n\n**Plano:** depende do módulo `agenda`.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:ler",
        "x-modulo": "agenda"
      }
    },
    "/agenda/{id}": {
      "get": {
        "operationId": "get_agenda_id",
        "tags": [
          "Agenda"
        ],
        "summary": "Ver um compromisso",
        "description": "Horário (ISO e de São Paulo), atendente, cliente, contato e situação.\n\n**Permissão da chave:** `agenda:ler` (Ler a agenda).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do compromisso"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:ler",
        "x-modulo": "agenda"
      }
    },
    "/agenda/{id}/remarcar": {
      "post": {
        "operationId": "post_agenda_id_remarcar",
        "tags": [
          "Agenda"
        ],
        "summary": "Remarcar",
        "description": "Novo horário em \"data\" + \"hora\" (São Paulo) ou \"inicio\" (ISO com fuso). A resposta traz o horário de antes.\n\n**Permissão da chave:** `agenda:gerenciar` (Marcar e remarcar).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do compromisso"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:gerenciar",
        "x-modulo": "agenda",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "data": "2026-09-30",
                "hora": "10:30"
              }
            }
          }
        }
      }
    },
    "/agenda/{id}/cancelar": {
      "post": {
        "operationId": "post_agenda_id_cancelar",
        "tags": [
          "Agenda"
        ],
        "summary": "Cancelar",
        "description": "Com \"motivo\" opcional.\n\n**Permissão da chave:** `agenda:gerenciar` (Marcar e remarcar).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do compromisso"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:gerenciar",
        "x-modulo": "agenda",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "motivo": "Cliente remarcou por telefone"
              }
            }
          }
        }
      }
    },
    "/agenda/{id}/concluir": {
      "post": {
        "operationId": "post_agenda_id_concluir",
        "tags": [
          "Agenda"
        ],
        "summary": "Dar baixa",
        "description": "\"compareceu\": true (realizado) ou false (faltou).\n\n**Permissão da chave:** `agenda:gerenciar` (Marcar e remarcar).\n\n**Plano:** depende do módulo `agenda`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do compromisso"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "agenda:gerenciar",
        "x-modulo": "agenda",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "compareceu": true
              }
            }
          }
        }
      }
    },
    "/tarefas": {
      "get": {
        "operationId": "get_tarefas",
        "tags": [
          "Tarefas"
        ],
        "summary": "Listar tarefas",
        "description": "Filtros: status (aberta, concluida, cancelada), tipo, responsavel (id ou \"eu\"), cliente (ext:, tel:, id), prazoDesde e prazoAte (ISO). Abertas vêm por prazo mais próximo; fechadas, pelas mais recentes. Paginação por \"cursor\"; \"limite\" até 100.\n\n**Permissão da chave:** `tarefas:ler` (Ler tarefas).",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "aberta",
                "concluida",
                "cancelada"
              ]
            },
            "description": "aberta, concluida ou cancelada"
          },
          {
            "name": "tipo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Código do tipo (veja GET /v1/tarefas/tipos)"
          },
          {
            "name": "responsavel",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Id do responsável ou \"eu\""
          },
          {
            "name": "cliente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone> ou o id do CRM"
          },
          {
            "name": "prazoDesde",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Prazo a partir deste instante (ISO)"
          },
          {
            "name": "prazoAte",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Prazo até este instante (ISO)"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 100; padrão 30)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior (paginação)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:ler"
      },
      "post": {
        "operationId": "post_tarefas",
        "tags": [
          "Tarefas"
        ],
        "summary": "Criar tarefa",
        "description": "Presa a um \"cliente\" (ext:, tel:, id) ou a uma \"oportunidade\". \"prazo\" é ISO com fuso; \"responsavel\", id ou \"eu\" (padrão: quem é dono da chave).\n\n**Permissão da chave:** `tarefas:gerenciar` (Criar e concluir tarefas).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "cliente": "ext:ERP-1042",
                "titulo": "Ligar para confirmar a entrega",
                "tipo": "ligacao",
                "prazo": "2026-09-26T16:00:00-03:00"
              }
            }
          }
        }
      }
    },
    "/tarefas/tipos": {
      "get": {
        "operationId": "get_tarefas_tipos",
        "tags": [
          "Tarefas"
        ],
        "summary": "Tipos de tarefa",
        "description": "Os códigos que \"tipo\" aceita (retorno, ligacao, whatsapp, documento, proposta, acompanhamento, geral).\n\n**Permissão da chave:** `tarefas:ler` (Ler tarefas).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:ler"
      }
    },
    "/tarefas/{id}": {
      "get": {
        "operationId": "get_tarefas_id",
        "tags": [
          "Tarefas"
        ],
        "summary": "Ver uma tarefa",
        "description": "Com o cliente, o responsável e se está vencida.\n\n**Permissão da chave:** `tarefas:ler` (Ler tarefas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da tarefa"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:ler"
      },
      "patch": {
        "operationId": "patch_tarefas_id",
        "tags": [
          "Tarefas"
        ],
        "summary": "Editar tarefa",
        "description": "Muda titulo, descricao, tipo, prazo ou responsavel. Só tarefa aberta se edita (409 se já foi concluída ou cancelada).\n\n**Permissão da chave:** `tarefas:gerenciar` (Criar e concluir tarefas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da tarefa"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "prazo": "2026-09-27T10:00:00-03:00"
              }
            }
          }
        }
      }
    },
    "/tarefas/{id}/concluir": {
      "post": {
        "operationId": "post_tarefas_id_concluir",
        "tags": [
          "Tarefas"
        ],
        "summary": "Concluir",
        "description": "Repetir não erra: a resposta diz \"jaEstava\".\n\n**Permissão da chave:** `tarefas:gerenciar` (Criar e concluir tarefas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da tarefa"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/tarefas/{id}/cancelar": {
      "post": {
        "operationId": "post_tarefas_id_cancelar",
        "tags": [
          "Tarefas"
        ],
        "summary": "Cancelar",
        "description": "Repetir não erra: a resposta diz \"jaEstava\".\n\n**Permissão da chave:** `tarefas:gerenciar` (Criar e concluir tarefas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da tarefa"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "tarefas:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/relatorios": {
      "get": {
        "operationId": "get_relatorios",
        "tags": [
          "Relatórios (BI)"
        ],
        "summary": "Conjuntos disponíveis",
        "description": "Os mesmos conjuntos do Power BI e do painel de Relatórios (mensagens, atendimentos, leads, propostas, ligações, custo de IA, resumo diário…), com o grão de cada um e quais exigem \"dados-pessoais:ler\".\n\n**Permissão da chave:** `relatorios:ler` (Ler relatórios (BI)).\n\n**Plano:** depende do módulo `relatorios_avancados`.",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "relatorios:ler",
        "x-modulo": "relatorios_avancados"
      }
    },
    "/relatorios/{conjunto}": {
      "get": {
        "operationId": "get_relatorios_conjunto",
        "tags": [
          "Relatórios (BI)"
        ],
        "summary": "Linhas de um conjunto",
        "description": "Janela por \"desde\" e \"ate\" (ISO), paginação por \"cursor\" (o \"proximo\" da página anterior; nulo = acabou), \"limite\" até 10.000. Instantes em UTC; colunas *_brt já no dia de São Paulo. Nome, CPF e telefone só aparecem com \"dados-pessoais:ler\".\n\n**Permissão da chave:** `relatorios:ler` (Ler relatórios (BI)).\n\n**Plano:** depende do módulo `relatorios_avancados`.",
        "parameters": [
          {
            "name": "conjunto",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O conjunto (veja GET /v1/relatorios)"
          },
          {
            "name": "desde",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Início da janela (ISO; data ou data e hora)"
          },
          {
            "name": "ate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Fim da janela (ISO)"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 10000; padrão 1000)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior (paginação)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "relatorios:ler",
        "x-modulo": "relatorios_avancados"
      }
    },
    "/ligacoes": {
      "get": {
        "operationId": "get_ligacoes",
        "tags": [
          "Ligações"
        ],
        "summary": "Listar ligações",
        "description": "Das mais recentes para trás. Filtros: desde, ate (ISO), canal (voip, whatsapp), desfecho (ATENDIDA, NAO_ATENDEU, CAIXA_POSTAL, OCUPADO…), resultado (ou SEM_SINAL), cliente. O telefone vem mascarado, a não ser com \"dados-pessoais:ler\" e o perfil que pode exportar ligações.\n\n**Permissão da chave:** `ligacoes:ler` (Ler ligações).\n\n**Plano:** depende do módulo `discador` ou `ligacoes_whatsapp`.",
        "parameters": [
          {
            "name": "desde",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A partir deste instante (ISO)"
          },
          {
            "name": "ate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Até este instante (ISO)"
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "voip",
                "whatsapp"
              ]
            },
            "description": "voip ou whatsapp"
          },
          {
            "name": "desfecho",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ATENDIDA, NAO_ATENDEU, CAIXA_POSTAL, OCUPADO, NUMERO_INVALIDO, FALHA…"
          },
          {
            "name": "resultado",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O resultado da conversa, ou SEM_SINAL"
          },
          {
            "name": "cliente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone> ou o id do CRM"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 200; padrão 50)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "O \"proximo\" da página anterior (paginação)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "ligacoes:ler",
        "x-modulo": [
          "discador",
          "ligacoes_whatsapp"
        ]
      }
    },
    "/ligacoes/{id}": {
      "get": {
        "operationId": "get_ligacoes_id",
        "tags": [
          "Ligações"
        ],
        "summary": "Ver uma ligação",
        "description": "Desfecho, resultado da conversa, duração, custo e, com \"dados-pessoais:ler\", a transcrição.\n\n**Permissão da chave:** `ligacoes:ler` (Ler ligações).\n\n**Plano:** depende do módulo `discador` ou `ligacoes_whatsapp`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da ligação (veja GET /v1/ligacoes)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "ligacoes:ler",
        "x-modulo": [
          "discador",
          "ligacoes_whatsapp"
        ]
      }
    },
    "/ligacoes/{id}/gravacao": {
      "get": {
        "operationId": "get_ligacoes_id_gravacao",
        "tags": [
          "Ligações"
        ],
        "summary": "Baixar a gravação",
        "description": "O áudio da ligação (WAV). Sai com as duas vozes misturadas, para ouvir; \"estereo=true\" devolve o original, cliente à esquerda e IA à direita. É a voz do cliente: exige \"dados-pessoais:ler\" e o perfil que ouve gravação na tela. Ligação não gravada: 404 sem_gravacao.\n\n**Permissão da chave:** `ligacoes:ler` (Ler ligações).\n\n**Plano:** depende do módulo `discador` ou `ligacoes_whatsapp`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da ligação (veja GET /v1/ligacoes)"
          },
          {
            "name": "estereo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true devolve os dois canais separados (cliente à esquerda, IA à direita); padrão: mono"
          }
        ],
        "responses": {
          "200": {
            "description": "O arquivo, com o Content-Type dele",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "ligacoes:ler",
        "x-modulo": [
          "discador",
          "ligacoes_whatsapp"
        ]
      }
    },
    "/conversas/{id}/ligar": {
      "post": {
        "operationId": "post_conversas_id_ligar",
        "tags": [
          "Ligações"
        ],
        "summary": "Ligar pelo WhatsApp (IA)",
        "description": "A IA de voz liga para o contato desta conversa pelo WhatsApp — a mesma ligação do botão do chat, com o agente, a voz e o roteiro configurados. Exige o módulo de ligações por WhatsApp. Teto próprio (padrão 10/min e 200/dia).\n\n**Permissão da chave:** `ligacoes:fazer` (Fazer ligações com IA).\n\n**Plano:** depende do módulo `ligacoes_whatsapp`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da conversa (veja GET /v1/conversas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "502": {
            "description": "O serviço de voz não aceitou o pedido agora — tente de novo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "ligacoes:fazer",
        "x-modulo": "ligacoes_whatsapp",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/clientes/{ref}/ligar": {
      "post": {
        "operationId": "post_clientes_ref_ligar",
        "tags": [
          "Ligações"
        ],
        "summary": "Ligar para o cliente (VoIP ou WhatsApp)",
        "description": "\"canal\": voip (padrão — o \"rediscar\" do discador, com o roteiro dele e as travas de não ligar, não perturbe e teto de tentativas) ou whatsapp (pela última conversa de WhatsApp do cliente). A resposta traz o \"ligacaoId\"; o desfecho chega pelo aviso ligacao.encerrada ou em GET /v1/ligacoes/{id}.\n\n**Permissão da chave:** `ligacoes:fazer` (Fazer ligações com IA).\n\n**Plano:** depende do módulo `discador` ou `ligacoes_whatsapp`.",
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O cliente: ext:<código do seu sistema>, tel:<telefone>, cpf:<cpf> ou o id do CRM"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "502": {
            "description": "O serviço de voz não aceitou o pedido agora — tente de novo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "ligacoes:fazer",
        "x-modulo": [
          "discador",
          "ligacoes_whatsapp"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "canal": "voip"
              }
            }
          }
        }
      }
    },
    "/usuarios": {
      "get": {
        "operationId": "get_usuarios",
        "tags": [
          "Administração"
        ],
        "summary": "Usuários",
        "description": "A equipe da empresa: perfil, se está ativo, filas, equipes, canais e telas bloqueadas, e a presença. O telefone só vem com \"dados-pessoais:ler\". Até 500.\n\n**Permissão da chave:** `usuarios:ler` (Ver usuários e equipes).",
        "parameters": [
          {
            "name": "ativos",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true: só quem está ativo; false: só os desativados; sem ele, todos"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:ler"
      },
      "post": {
        "operationId": "post_usuarios",
        "tags": [
          "Administração"
        ],
        "summary": "Criar usuário",
        "description": "Cria a pessoa e manda o convite: o e-mail de escolher senha (a API nunca define senha; \"convidar\": false não manda). \"perfil\" padrão: atendente; atendente e operador bastam \"usuarios:gerenciar\", qualquer outro pede \"usuarios:acesso\", e administrador não se cria pela API. Ocupa uma vaga do plano: sem vaga, 409 limite_do_plano. \"filas\" (GET /v1/filas), \"canaisPermitidos\" (o \"canal\" de GET /v1/canais; vazio = todos) e \"telasBloqueadas\" são conferidos antes de gravar. Só administrador ou gestor.\n\n**Permissão da chave:** `usuarios:gerenciar` (Cadastrar e ajustar usuários).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Ana Lima",
                "email": "ana@empresa.com.br",
                "perfil": "atendente",
                "filas": [
                  "<id da fila>"
                ],
                "maxAtendimentos": 5
              }
            }
          }
        }
      }
    },
    "/usuarios/{id}": {
      "get": {
        "operationId": "get_usuarios_id",
        "tags": [
          "Administração"
        ],
        "summary": "Ver um usuário",
        "description": "O mesmo de GET /v1/usuarios, de uma pessoa.\n\n**Permissão da chave:** `usuarios:ler` (Ver usuários e equipes).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do usuário (veja GET /v1/usuarios)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:ler"
      },
      "patch": {
        "operationId": "patch_usuarios_id",
        "tags": [
          "Administração"
        ],
        "summary": "Editar usuário",
        "description": "Muda só o que vier; o resto do cadastro fica como está. Trocar \"perfil\" ou \"email\" pede também \"usuarios:acesso\". Não se alteram pela API: administradores, a pessoa dona da chave e contas de parceiro ou da plataforma (403 usuario_protegido). Quem também atende outra empresa só muda nome, telefone, cor e filas (409 conta_compartilhada). \"filas\" aqui é a lista completa.\n\n**Permissão da chave:** `usuarios:gerenciar` (Cadastrar e ajustar usuários).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do usuário (veja GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "maxAtendimentos": 8,
                "veTodoOSetor": true
              }
            }
          }
        }
      }
    },
    "/usuarios/{id}/filas": {
      "put": {
        "operationId": "put_usuarios_id_filas",
        "tags": [
          "Administração"
        ],
        "summary": "Filas do usuário",
        "description": "\"filas\" é a lista COMPLETA (vazia tira de todas). Para pôr ou tirar um administrador de uma fila, use PUT /v1/filas/{id}/atendentes.\n\n**Permissão da chave:** `usuarios:gerenciar` (Cadastrar e ajustar usuários).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do usuário (veja GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "filas": [
                  "<id da fila>"
                ]
              }
            }
          }
        }
      }
    },
    "/usuarios/{id}/desativar": {
      "post": {
        "operationId": "post_usuarios_id_desativar",
        "tags": [
          "Administração"
        ],
        "summary": "Desativar usuário",
        "description": "Corta o acesso na hora (derruba as sessões). Repetir não desfaz: \"mudou\": false quando já estava desativado.\n\n**Permissão da chave:** `usuarios:gerenciar` (Cadastrar e ajustar usuários).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do usuário (veja GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/usuarios/{id}/reativar": {
      "post": {
        "operationId": "post_usuarios_id_reativar",
        "tags": [
          "Administração"
        ],
        "summary": "Reativar usuário",
        "description": "Ocupa de novo uma vaga do plano (sem vaga, 409 limite_do_plano). Repetir não desfaz.\n\n**Permissão da chave:** `usuarios:gerenciar` (Cadastrar e ajustar usuários).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do usuário (veja GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/usuarios/{id}/redefinir-senha": {
      "post": {
        "operationId": "post_usuarios_id_redefinir_senha",
        "tags": [
          "Administração"
        ],
        "summary": "Mandar redefinição de senha",
        "description": "A pessoa recebe o e-mail para escolher uma senha nova (vale 30 minutos). A API não vê nem define senha. Responde 202.\n\n**Permissão da chave:** `usuarios:acesso` (Mudar perfil, e-mail e senha).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do usuário (veja GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:acesso",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/equipes": {
      "get": {
        "operationId": "get_equipes",
        "tags": [
          "Administração"
        ],
        "summary": "Equipes",
        "description": "As equipes com gestor, membros (e o papel: membro ou supervisor) e quantos clientes estão na carteira de cada uma.\n\n**Permissão da chave:** `usuarios:ler` (Ver usuários e equipes).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "usuarios:ler"
      },
      "post": {
        "operationId": "post_equipes",
        "tags": [
          "Administração"
        ],
        "summary": "Criar equipe",
        "description": "\"nome\" (único na empresa), \"descricao\" e \"gestor\" (id de usuário ativo). Só administrador ou gestor.\n\n**Permissão da chave:** `equipes:gerenciar` (Organizar equipes).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "equipes:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "nome": "Equipe Norte",
                "gestor": "<id do usuário>"
              }
            }
          }
        }
      }
    },
    "/equipes/{id}": {
      "patch": {
        "operationId": "patch_equipes_id",
        "tags": [
          "Administração"
        ],
        "summary": "Editar equipe",
        "description": "Muda só o que vier: nome, descricao, gestor, ativa. Desligar não apaga: os clientes continuam marcados com a equipe.\n\n**Permissão da chave:** `equipes:gerenciar` (Organizar equipes).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da equipe (veja GET /v1/equipes)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "equipes:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "ativa": false
              }
            }
          }
        }
      }
    },
    "/equipes/{id}/membros/{usuario}": {
      "put": {
        "operationId": "put_equipes_id_membros_usuario",
        "tags": [
          "Administração"
        ],
        "summary": "Pôr alguém na equipe",
        "description": "\"papel\": membro (padrão) ou supervisor. Quem já está tem o papel trocado. Só usuário ativo.\n\n**Permissão da chave:** `equipes:gerenciar` (Organizar equipes).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da equipe (veja GET /v1/equipes)"
          },
          {
            "name": "usuario",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O usuário (id, de GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "equipes:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "papel": "membro"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_equipes_id_membros_usuario",
        "tags": [
          "Administração"
        ],
        "summary": "Tirar alguém da equipe",
        "description": "Os clientes da pessoa NÃO voltam junto: a resposta diz quantos continuam com ela (\"clientesQueFicaramComEla\").\n\n**Permissão da chave:** `equipes:gerenciar` (Organizar equipes).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da equipe (veja GET /v1/equipes)"
          },
          {
            "name": "usuario",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O usuário (id, de GET /v1/usuarios)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "equipes:gerenciar"
      }
    },
    "/filas/{id}": {
      "get": {
        "operationId": "get_filas_id",
        "tags": [
          "Administração"
        ],
        "summary": "Ver uma fila",
        "description": "A configuração da fila: agente de IA, fluxo, mensagens, horário por dia e quem atende. O webhook da fila não sai (é credencial).\n\n**Permissão da chave:** `conversas:ler` (Ler conversas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da fila (veja GET /v1/filas)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "conversas:ler"
      },
      "patch": {
        "operationId": "patch_filas_id",
        "tags": [
          "Administração"
        ],
        "summary": "Editar fila",
        "description": "Muda só o que vier, inclusive \"ativa\" (liga e desliga). O webhook da fila fica como está.\n\n**Permissão da chave:** `filas:gerenciar` (Configurar filas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da fila (veja GET /v1/filas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "filas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "mensagemForaDoHorario": "Voltamos amanhã às 8h."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_filas_id",
        "tags": [
          "Administração"
        ],
        "summary": "Excluir fila",
        "description": "Recusa (422) enquanto alguma conexão estiver ligada a ela.\n\n**Permissão da chave:** `filas:gerenciar` (Configurar filas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da fila (veja GET /v1/filas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "filas:gerenciar"
      }
    },
    "/filas/{id}/atendentes": {
      "put": {
        "operationId": "put_filas_id_atendentes",
        "tags": [
          "Administração"
        ],
        "summary": "Quem atende na fila",
        "description": "\"atendentes\" é a lista COMPLETA de ids de usuário (vazia tira todos).\n\n**Permissão da chave:** `filas:gerenciar` (Configurar filas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id da fila (veja GET /v1/filas)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "filas:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "atendentes": [
                  "<id do usuário>"
                ]
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "operationId": "get_webhooks",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Listar webhooks",
        "description": "Os webhooks que ESTA chave cadastrou, com os eventos de cada um. Os cadastrados na tela ou por outra chave não aparecem.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar"
      },
      "post": {
        "operationId": "post_webhooks",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Cadastrar webhook",
        "description": "O endereço precisa ser https e público. A resposta traz o \"segredo\" UMA vez: ele assina cada aviso (cabeçalho X-InstaCRM-Assinatura: t=<unix>,v1=<HMAC-SHA256 de \"<t>.<corpo>\">). Cada aviso exige também a permissão de ler o assunto dele (ex.: \"mensagem.recebida\" pede \"conversas:ler\"; \"ligacao.encerrada\", \"ligacoes:ler\"), e a chave precisa ser de quem enxerga a operação inteira (administrador ou gestor), porque os avisos são da empresa toda. Revogar a chave desliga os webhooks dela.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "url": "https://meu-erp.com.br/instacrm/avisos",
                "eventos": [
                  "etiqueta.aplicada",
                  "mensagem.recebida"
                ],
                "descricao": "ERP da loja"
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "patch": {
        "operationId": "patch_webhooks_id",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Editar webhook",
        "description": "Muda url, eventos, descrição ou liga/desliga um webhook desta chave. Religar zera o contador de falhas; aviso novo pede a permissão de ler o assunto dele.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do webhook (veja GET /v1/webhooks)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "ativo": true
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_webhooks_id",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Apagar webhook",
        "description": "Apaga o webhook e as entregas dele.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do webhook (veja GET /v1/webhooks)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar"
      }
    },
    "/webhooks/{id}/testar": {
      "post": {
        "operationId": "post_webhooks_id_testar",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Mandar aviso de teste",
        "description": "Manda um aviso \"teste\" assinado e diz o que o endereço respondeu.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do webhook (veja GET /v1/webhooks)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/segredo": {
      "post": {
        "operationId": "post_webhooks_id_segredo",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Trocar o segredo",
        "description": "Gera um segredo novo (o antigo para de valer na hora) e mostra UMA vez.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do webhook (veja GET /v1/webhooks)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/entregas": {
      "get": {
        "operationId": "get_webhooks_id_entregas",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Entregas recentes",
        "description": "Cada aviso, se chegou, quantas tentativas e o último erro.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do webhook (veja GET /v1/webhooks)"
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Itens por página (até 200; padrão 50)"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar"
      }
    },
    "/webhooks/{id}/entregas/{entrega}/reenviar": {
      "post": {
        "operationId": "post_webhooks_id_entregas_entrega_reenviar",
        "tags": [
          "Avisos (webhooks)"
        ],
        "summary": "Reenviar um aviso",
        "description": "Volta a entrega para a fila, do zero.\n\n**Permissão da chave:** `webhooks:gerenciar` (Gerenciar webhooks).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "O id do webhook (veja GET /v1/webhooks)"
          },
          {
            "name": "entrega",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A entrega (id)"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Um código único por operação. Repetir o pedido com o mesmo código devolve a mesma resposta sem refazer."
          }
        ],
        "responses": {
          "400": {
            "description": "Corpo que não é JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida, revogada ou vencida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "403": {
            "description": "Sem a permissão (escopo), IP fora da lista ou módulo não contratado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado (ou fora do que a chave enxerga)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "Conflito (código externo já usado, pedido repetido em andamento, conversa já assumida ou encerrada, horário tomado…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "Pedido recusado pela regra (dado inválido, fora da janela, não perturbe…)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "description": "Limite de ritmo atingido — espere o Retry-After",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "segundos até poder repetir"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "2XX": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-escopo": "webhooks:gerenciar",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "mensagem.recebida": {
      "post": {
        "operationId": "aviso_mensagem_recebida",
        "summary": "Mensagem recebida",
        "description": "Cada mensagem que o cliente manda (fora de grupo): o texto, o id, o arquivo para baixar e o botão, a opção de lista ou o voto de enquete que ele tocou. Enviado para cada webhook cadastrado que assinou `mensagem.recebida`.",
        "tags": [
          "Avisos — Mensagens"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "mensagem.recebida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "mensagem.status": {
      "post": {
        "operationId": "aviso_mensagem_status",
        "summary": "Situação da mensagem",
        "description": "Entregue, lida ou falhou (mensagens enviadas pela API). Enviado para cada webhook cadastrado que assinou `mensagem.status`.",
        "tags": [
          "Avisos — Mensagens"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "mensagem.status"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "cliente.criado": {
      "post": {
        "operationId": "aviso_cliente_criado",
        "summary": "Cliente criado",
        "description": "Cliente novo cadastrado pela API. Enviado para cada webhook cadastrado que assinou `cliente.criado`.",
        "tags": [
          "Avisos — Clientes"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "cliente.criado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "cliente.etapa_alterada": {
      "post": {
        "operationId": "aviso_cliente_etapa_alterada",
        "summary": "Cliente mudou de etapa",
        "description": "Venha de onde vier: funil, etiqueta, gatilho, fluxo, IA, lote, CLT, FGTS ou API (o campo \"origem\" diz qual). Enviado para cada webhook cadastrado que assinou `cliente.etapa_alterada`.",
        "tags": [
          "Avisos — Clientes"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "cliente.etapa_alterada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "etiqueta.aplicada": {
      "post": {
        "operationId": "aviso_etiqueta_aplicada",
        "summary": "Etiqueta aplicada",
        "description": "Por quem quer que seja: tela, IA, fluxo, FGTS ou API. Enviado para cada webhook cadastrado que assinou `etiqueta.aplicada`.",
        "tags": [
          "Avisos — Etiquetas"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "etiqueta.aplicada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "etiqueta.removida": {
      "post": {
        "operationId": "aviso_etiqueta_removida",
        "summary": "Etiqueta removida",
        "description": "Tirada pela tela, pelo fluxo ou pela API. Enviado para cada webhook cadastrado que assinou `etiqueta.removida`.",
        "tags": [
          "Avisos — Etiquetas"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "etiqueta.removida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.transferida": {
      "post": {
        "operationId": "aviso_conversa_transferida",
        "summary": "Conversa transferida",
        "description": "Mudou de fila ou de atendente: pela tela, pela IA, na troca de agente ou pela API. Enviado para cada webhook cadastrado que assinou `conversa.transferida`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.transferida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.encerrada": {
      "post": {
        "operationId": "aviso_conversa_encerrada",
        "summary": "Conversa encerrada",
        "description": "Pela tela, pela API, pela IA ou por inatividade. Enviado para cada webhook cadastrado que assinou `conversa.encerrada`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.encerrada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.atribuida": {
      "post": {
        "operationId": "aviso_conversa_atribuida",
        "summary": "Conversa atribuída",
        "description": "Alguém assumiu a conversa (pela tela, pela API, pela carteira ou ao responder primeiro), ou ela voltou para a IA. Enviado para cada webhook cadastrado que assinou `conversa.atribuida`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.atribuida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.reaberta": {
      "post": {
        "operationId": "aviso_conversa_reaberta",
        "summary": "Conversa reaberta",
        "description": "Um atendimento encerrado voltou a ficar aberto: pela tela, pela API ou porque o cliente escreveu. Enviado para cada webhook cadastrado que assinou `conversa.reaberta`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.reaberta"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "publicacao.publicada": {
      "post": {
        "operationId": "aviso_publicacao_publicada",
        "summary": "Publicação no ar",
        "description": "O post saiu, com o link. Enviado para cada webhook cadastrado que assinou `publicacao.publicada`.",
        "tags": [
          "Avisos — Publicações"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "publicacao.publicada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "publicacao.falhou": {
      "post": {
        "operationId": "aviso_publicacao_falhou",
        "summary": "Publicação falhou",
        "description": "O post não saiu, com o motivo. Enviado para cada webhook cadastrado que assinou `publicacao.falhou`.",
        "tags": [
          "Avisos — Publicações"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "publicacao.falhou"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "campanha.concluida": {
      "post": {
        "operationId": "aviso_campanha_concluida",
        "summary": "Campanha concluída",
        "description": "O disparo terminou. Enviado para cada webhook cadastrado que assinou `campanha.concluida`.",
        "tags": [
          "Avisos — Disparos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "campanha.concluida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "agendamento.criado": {
      "post": {
        "operationId": "aviso_agendamento_criado",
        "summary": "Compromisso marcado",
        "description": "Pela tela, pela IA na conversa ou pela API. Enviado para cada webhook cadastrado que assinou `agendamento.criado`.",
        "tags": [
          "Avisos — Agenda"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "agendamento.criado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "agendamento.remarcado": {
      "post": {
        "operationId": "aviso_agendamento_remarcado",
        "summary": "Compromisso remarcado",
        "description": "Com o horário de antes e o novo. Enviado para cada webhook cadastrado que assinou `agendamento.remarcado`.",
        "tags": [
          "Avisos — Agenda"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "agendamento.remarcado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "agendamento.confirmado": {
      "post": {
        "operationId": "aviso_agendamento_confirmado",
        "summary": "Compromisso confirmado",
        "description": "Pelo cliente (botão ou resposta no WhatsApp, ou na ligação de confirmação) ou pela equipe — o campo \"por\" diz quem. Enviado para cada webhook cadastrado que assinou `agendamento.confirmado`.",
        "tags": [
          "Avisos — Agenda"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "agendamento.confirmado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "agendamento.cancelado": {
      "post": {
        "operationId": "aviso_agendamento_cancelado",
        "summary": "Compromisso cancelado",
        "description": "Com o motivo. Enviado para cada webhook cadastrado que assinou `agendamento.cancelado`.",
        "tags": [
          "Avisos — Agenda"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "agendamento.cancelado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "agendamento.concluido": {
      "post": {
        "operationId": "aviso_agendamento_concluido",
        "summary": "Compromisso concluído",
        "description": "Realizado ou falta. Enviado para cada webhook cadastrado que assinou `agendamento.concluido`.",
        "tags": [
          "Avisos — Agenda"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "agendamento.concluido"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "tarefa.criada": {
      "post": {
        "operationId": "aviso_tarefa_criada",
        "summary": "Tarefa criada",
        "description": "Pela equipe, pela API ou automática. Enviado para cada webhook cadastrado que assinou `tarefa.criada`.",
        "tags": [
          "Avisos — Tarefas"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "tarefa.criada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "tarefa.concluida": {
      "post": {
        "operationId": "aviso_tarefa_concluida",
        "summary": "Tarefa concluída",
        "description": "Dada por feita. Enviado para cada webhook cadastrado que assinou `tarefa.concluida`.",
        "tags": [
          "Avisos — Tarefas"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "tarefa.concluida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "tarefa.cancelada": {
      "post": {
        "operationId": "aviso_tarefa_cancelada",
        "summary": "Tarefa cancelada",
        "description": "Não precisa mais. Enviado para cada webhook cadastrado que assinou `tarefa.cancelada`.",
        "tags": [
          "Avisos — Tarefas"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "tarefa.cancelada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "ligacao.encerrada": {
      "post": {
        "operationId": "aviso_ligacao_encerrada",
        "summary": "Ligação encerrada",
        "description": "Desfecho, duração e resultado da ligação com IA. Enviado para cada webhook cadastrado que assinou `ligacao.encerrada`.",
        "tags": [
          "Avisos — Ligações"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "ligacao.encerrada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.criada": {
      "post": {
        "operationId": "aviso_conversa_criada",
        "summary": "Conversa nova",
        "description": "Pelo cliente, pelo celular da empresa, por um atendente, pela API, pelo webchat, pela ligação ou pelo endereço da fila (o campo \"origem\" diz qual). Enviado para cada webhook cadastrado que assinou `conversa.criada`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.criada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.ia_pausada": {
      "post": {
        "operationId": "aviso_conversa_ia_pausada",
        "summary": "IA pausada na conversa",
        "description": "Pela tela, pela API, pelo fluxo ou pela própria IA (o cliente pediu uma pessoa). Enviado para cada webhook cadastrado que assinou `conversa.ia_pausada`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.ia_pausada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "conversa.ia_retomada": {
      "post": {
        "operationId": "aviso_conversa_ia_retomada",
        "summary": "IA retomada na conversa",
        "description": "A IA voltou a responder nesta conversa (pela tela ou pela API). Enviado para cada webhook cadastrado que assinou `conversa.ia_retomada`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "conversa.ia_retomada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "pesquisa.respondida": {
      "post": {
        "operationId": "aviso_pesquisa_respondida",
        "summary": "Pesquisa respondida",
        "description": "A nota (1 a 5) e o comentário da pesquisa de satisfação. Enviado para cada webhook cadastrado que assinou `pesquisa.respondida`.",
        "tags": [
          "Avisos — Atendimento"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "pesquisa.respondida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "mensagem.enviada": {
      "post": {
        "operationId": "aviso_mensagem_enviada",
        "summary": "Mensagem enviada",
        "description": "Cada mensagem que sai para o cliente (atendente, IA, API, sistema), com o texto. Sem nota interna e sem grupo. Enviado para cada webhook cadastrado que assinou `mensagem.enviada`.",
        "tags": [
          "Avisos — Mensagens"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "mensagem.enviada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "cliente.atualizado": {
      "post": {
        "operationId": "aviso_cliente_atualizado",
        "summary": "Cliente atualizado",
        "description": "O cadastro mudou (nome, telefone, e-mail, etiquetas…), com a lista do que mudou. Enviado para cada webhook cadastrado que assinou `cliente.atualizado`.",
        "tags": [
          "Avisos — Clientes"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "cliente.atualizado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "cliente.excluido": {
      "post": {
        "operationId": "aviso_cliente_excluido",
        "summary": "Cliente excluído",
        "description": "Apagado de vez, pela tela ou pela API. Enviado para cada webhook cadastrado que assinou `cliente.excluido`.",
        "tags": [
          "Avisos — Clientes"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "cliente.excluido"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "cliente.descadastrado": {
      "post": {
        "operationId": "aviso_cliente_descadastrado",
        "summary": "Cliente pediu para sair",
        "description": "Pediu para não ser mais chamado (na ligação) ou saiu da lista de e-mail. Enviado para cada webhook cadastrado que assinou `cliente.descadastrado`.",
        "tags": [
          "Avisos — Clientes"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "cliente.descadastrado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "campanha.iniciada": {
      "post": {
        "operationId": "aviso_campanha_iniciada",
        "summary": "Campanha iniciada",
        "description": "O disparo começou. Enviado para cada webhook cadastrado que assinou `campanha.iniciada`.",
        "tags": [
          "Avisos — Disparos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "campanha.iniciada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "campanha.pausada": {
      "post": {
        "operationId": "aviso_campanha_pausada",
        "summary": "Campanha pausada",
        "description": "Pela tela, pela API, pela chave geral das automações ou pelo teto diário. Enviado para cada webhook cadastrado que assinou `campanha.pausada`.",
        "tags": [
          "Avisos — Disparos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "campanha.pausada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "campanha.retomada": {
      "post": {
        "operationId": "aviso_campanha_retomada",
        "summary": "Campanha retomada",
        "description": "O disparo pausado voltou a sair. Enviado para cada webhook cadastrado que assinou `campanha.retomada`.",
        "tags": [
          "Avisos — Disparos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "campanha.retomada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "campanha.cancelada": {
      "post": {
        "operationId": "aviso_campanha_cancelada",
        "summary": "Campanha cancelada",
        "description": "O disparo parou de vez. Enviado para cada webhook cadastrado que assinou `campanha.cancelada`.",
        "tags": [
          "Avisos — Disparos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "campanha.cancelada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "campanha.respondida": {
      "post": {
        "operationId": "aviso_campanha_respondida",
        "summary": "Campanha respondida",
        "description": "O cliente respondeu a um disparo (só os ids e os horários). Enviado para cada webhook cadastrado que assinou `campanha.respondida`.",
        "tags": [
          "Avisos — Disparos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "campanha.respondida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "canal.conectado": {
      "post": {
        "operationId": "aviso_canal_conectado",
        "summary": "Canal conectado",
        "description": "O WhatsApp por QR conectou (ou voltou a conectar). Enviado para cada webhook cadastrado que assinou `canal.conectado`.",
        "tags": [
          "Avisos — Canais"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "canal.conectado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "canal.desconectado": {
      "post": {
        "operationId": "aviso_canal_desconectado",
        "summary": "Canal desconectado",
        "description": "O WhatsApp por QR caiu ou foi desconectado, ou o token do número oficial não renovou. Enviado para cada webhook cadastrado que assinou `canal.desconectado`.",
        "tags": [
          "Avisos — Canais"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "canal.desconectado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "canal.restrito": {
      "post": {
        "operationId": "aviso_canal_restrito",
        "summary": "Canal restrito",
        "description": "Número banido, ou travado pelo disjuntor da API oficial (com o motivo e até quando). Enviado para cada webhook cadastrado que assinou `canal.restrito`.",
        "tags": [
          "Avisos — Canais"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "canal.restrito"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "tarefa.atualizada": {
      "post": {
        "operationId": "aviso_tarefa_atualizada",
        "summary": "Tarefa atualizada",
        "description": "Mudou o título, o prazo, o tipo ou o responsável — com a lista do que mudou. Enviado para cada webhook cadastrado que assinou `tarefa.atualizada`.",
        "tags": [
          "Avisos — Tarefas"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "tarefa.atualizada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "agendamento.lembrete_enviado": {
      "post": {
        "operationId": "aviso_agendamento_lembrete_enviado",
        "summary": "Lembrete enviado",
        "description": "O lembrete do compromisso saiu para o cliente. Enviado para cada webhook cadastrado que assinou `agendamento.lembrete_enviado`.",
        "tags": [
          "Avisos — Agenda"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "agendamento.lembrete_enviado"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "publicacao.agendada": {
      "post": {
        "operationId": "aviso_publicacao_agendada",
        "summary": "Publicação agendada",
        "description": "Entrou na fila (ou mudou de hora), pela tela, pela API ou pela IA. Enviado para cada webhook cadastrado que assinou `publicacao.agendada`.",
        "tags": [
          "Avisos — Publicações"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "publicacao.agendada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "publicacao.cancelada": {
      "post": {
        "operationId": "aviso_publicacao_cancelada",
        "summary": "Publicação cancelada",
        "description": "Saiu da fila antes de publicar. Enviado para cada webhook cadastrado que assinou `publicacao.cancelada`.",
        "tags": [
          "Avisos — Publicações"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "publicacao.cancelada"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    },
    "grupo.mensagem_recebida": {
      "post": {
        "operationId": "aviso_grupo_mensagem_recebida",
        "summary": "Mensagem em grupo",
        "description": "Cada mensagem num grupo de WhatsApp (QR code), com o grupo e quem escreveu. Separado de \"mensagem recebida\" para robô de resposta não responder em grupo sem ter pedido. Enviado para cada webhook cadastrado que assinou `grupo.mensagem_recebida`.",
        "tags": [
          "Avisos — Grupos"
        ],
        "parameters": [
          {
            "name": "X-InstaCRM-Evento",
            "in": "header",
            "schema": {
              "type": "string",
              "const": "grupo.mensagem_recebida"
            }
          },
          {
            "name": "X-InstaCRM-Entrega",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-InstaCRM-Assinatura",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256 de \"<t>.<corpo cru>\"> com o segredo do webhook"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Aviso"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebido. Qualquer outra resposta (ou 10 s sem resposta) é nova tentativa."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "chave": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer icrm_live_…"
      },
      "chaveNoCabecalho": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    },
    "schemas": {
      "Erro": {
        "type": "object",
        "required": [
          "erro"
        ],
        "properties": {
          "erro": {
            "type": "object",
            "required": [
              "codigo",
              "mensagem"
            ],
            "properties": {
              "codigo": {
                "type": "string",
                "description": "Estável: compare este campo (ex.: escopo_insuficiente, fora_da_janela)."
              },
              "mensagem": {
                "type": "string",
                "description": "Para gente, em português."
              },
              "detalhes": {
                "type": "object"
              }
            }
          }
        }
      },
      "Aviso": {
        "type": "object",
        "required": [
          "id",
          "tipo",
          "criadoEm",
          "empresa",
          "dados"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Id do evento — o mesmo aviso pode chegar duas vezes; descarte o repetido por este campo."
          },
          "tipo": {
            "type": "string",
            "enum": [
              "mensagem.recebida",
              "mensagem.status",
              "cliente.criado",
              "cliente.etapa_alterada",
              "etiqueta.aplicada",
              "etiqueta.removida",
              "conversa.transferida",
              "conversa.encerrada",
              "conversa.atribuida",
              "conversa.reaberta",
              "publicacao.publicada",
              "publicacao.falhou",
              "campanha.concluida",
              "agendamento.criado",
              "agendamento.remarcado",
              "agendamento.confirmado",
              "agendamento.cancelado",
              "agendamento.concluido",
              "tarefa.criada",
              "tarefa.concluida",
              "tarefa.cancelada",
              "ligacao.encerrada",
              "conversa.criada",
              "conversa.ia_pausada",
              "conversa.ia_retomada",
              "pesquisa.respondida",
              "mensagem.enviada",
              "cliente.atualizado",
              "cliente.excluido",
              "cliente.descadastrado",
              "campanha.iniciada",
              "campanha.pausada",
              "campanha.retomada",
              "campanha.cancelada",
              "campanha.respondida",
              "canal.conectado",
              "canal.desconectado",
              "canal.restrito",
              "tarefa.atualizada",
              "agendamento.lembrete_enviado",
              "publicacao.agendada",
              "publicacao.cancelada",
              "grupo.mensagem_recebida"
            ]
          },
          "criadoEm": {
            "type": "string",
            "format": "date-time"
          },
          "empresa": {
            "type": "string"
          },
          "dados": {
            "type": "object"
          }
        }
      }
    }
  },
  "x-escopos": [
    {
      "id": "clientes:ler",
      "rotulo": "Ler clientes",
      "dica": "Buscar e listar clientes, ver o funil"
    },
    {
      "id": "clientes:escrever",
      "rotulo": "Criar e editar clientes",
      "dica": "Cadastrar, atualizar e mover no funil"
    },
    {
      "id": "clientes:excluir",
      "rotulo": "Excluir clientes",
      "dica": "Apagar cliente de vez (o mesmo excluir do funil). Até 100 por dia"
    },
    {
      "id": "dados-pessoais:ler",
      "rotulo": "Ver CPF e dados pessoais",
      "dica": "Sem este escopo o CPF nem aparece na resposta"
    },
    {
      "id": "etiquetas:ler",
      "rotulo": "Ler etiquetas",
      "dica": "Listar etiquetas e o histórico de aplicação"
    },
    {
      "id": "etiquetas:aplicar",
      "rotulo": "Aplicar e remover etiquetas",
      "dica": "Etiquetar clientes — dispara a automação da etiqueta"
    },
    {
      "id": "etiquetas:gerenciar",
      "rotulo": "Criar e editar etiquetas",
      "dica": "Mexer no cadastro de etiquetas"
    },
    {
      "id": "mensagens:enviar",
      "rotulo": "Enviar mensagens",
      "dica": "Mandar texto, mídia e template, e responder conversas em qualquer canal"
    },
    {
      "id": "mensagens:ler",
      "rotulo": "Ver situação de mensagens",
      "dica": "Enviada, entregue, lida ou falhou"
    },
    {
      "id": "grupos:ler",
      "rotulo": "Ver grupos de WhatsApp",
      "dica": "Os grupos do número por QR code, quem está em cada um, o link de convite e as mensagens dos grupos"
    },
    {
      "id": "grupos:gerenciar",
      "rotulo": "Administrar grupos de WhatsApp",
      "dica": "Criar grupo, pôr e tirar pessoas, trocar nome, descrição e convite, e sair do grupo"
    },
    {
      "id": "conversas:ler",
      "rotulo": "Ler conversas",
      "dica": "Listar e abrir conversas, ler o histórico, ver filas e atendentes"
    },
    {
      "id": "conversas:gerenciar",
      "rotulo": "Conduzir o atendimento",
      "dica": "Atribuir, transferir, devolver para a IA, encerrar, reabrir, notas, adiar e agendar mensagem"
    },
    {
      "id": "campanhas:ler",
      "rotulo": "Ler campanhas e templates",
      "dica": "Progresso, relatório e templates aprovados"
    },
    {
      "id": "campanhas:gerenciar",
      "rotulo": "Criar e controlar campanhas",
      "dica": "Criar disparo, iniciar, pausar e cancelar"
    },
    {
      "id": "publicacoes:ler",
      "rotulo": "Ler publicações",
      "dica": "Situação de cada post e onde dá para publicar"
    },
    {
      "id": "publicacoes:publicar",
      "rotulo": "Publicar no Instagram e no Status",
      "dica": "Subir mídia, publicar agora, agendar e cancelar"
    },
    {
      "id": "agenda:ler",
      "rotulo": "Ler a agenda",
      "dica": "Compromissos, horários livres e o expediente da equipe"
    },
    {
      "id": "agenda:gerenciar",
      "rotulo": "Marcar e remarcar",
      "dica": "Marcar, remarcar, cancelar e dar baixa em compromissos"
    },
    {
      "id": "tarefas:ler",
      "rotulo": "Ler tarefas",
      "dica": "Listar tarefas e os tipos"
    },
    {
      "id": "tarefas:gerenciar",
      "rotulo": "Criar e concluir tarefas",
      "dica": "Criar, editar, concluir e cancelar"
    },
    {
      "id": "relatorios:ler",
      "rotulo": "Ler relatórios (BI)",
      "dica": "Os mesmos conjuntos do Power BI. Colunas pessoais só com \"Ver CPF e dados pessoais\""
    },
    {
      "id": "ligacoes:ler",
      "rotulo": "Ler ligações",
      "dica": "Desfecho, duração e resultado de cada ligação"
    },
    {
      "id": "ligacoes:fazer",
      "rotulo": "Fazer ligações com IA",
      "dica": "A IA liga pelo WhatsApp ou pelo telefone (VoIP). Cada ligação custa minuto"
    },
    {
      "id": "webhooks:gerenciar",
      "rotulo": "Gerenciar webhooks",
      "dica": "Cadastrar os endereços que recebem os avisos. Cada aviso pede também a permissão de ler o assunto dele"
    },
    {
      "id": "usuarios:ler",
      "rotulo": "Ver usuários e equipes",
      "dica": "A equipe com perfil, filas, equipes e presença. O telefone só aparece com \"Ver CPF e dados pessoais\""
    },
    {
      "id": "usuarios:gerenciar",
      "rotulo": "Cadastrar e ajustar usuários",
      "dica": "Criar atendente (convite por e-mail), editar, trocar filas, desativar e reativar. Administradores e a pessoa dona da chave não se alteram pela API"
    },
    {
      "id": "usuarios:acesso",
      "rotulo": "Mudar perfil, e-mail e senha",
      "dica": "Dar outro perfil (nunca administrador), trocar o e-mail e mandar o e-mail de redefinir senha"
    },
    {
      "id": "equipes:gerenciar",
      "rotulo": "Organizar equipes",
      "dica": "Criar, renomear, ligar e desligar equipes; pôr e tirar pessoas. A equipe decide a distribuição de clientes"
    },
    {
      "id": "filas:gerenciar",
      "rotulo": "Configurar filas",
      "dica": "Criar, editar, ligar, desligar e excluir filas (departamentos): IA, fluxo, horário e quem atende"
    }
  ]
}
