{
  "openapi": "3.1.0",
  "info": {
    "title": "ZapHub API /v1",
    "version": "1.0.0",
    "description": "API pública do ZapHub: conecte o WhatsApp ao seu sistema (CRM, ERP, atendimento) sem depender do painel.\n\n**Autenticação:** `Authorization: Bearer <chave>` (chaves `zh_live_…`, até 10 ativas por conta, restringíveis a números).\n**Limite:** 600 requisições por minuto por chave (`429` com `Retry-After`; headers `X-RateLimit-*` em toda resposta). Não há limite por volume de mensagens.\n**Idempotência:** header `Idempotency-Key` nos POSTs de criação (24h).\n**Erros:** sempre `{ statusCode, code, message, fields? }`. Ramifique por `code`.\n**Ids:** sempre identificadores públicos (strings)."
  },
  "servers": [
    {
      "url": "https://api.zaphub.wssengenharia.com.br",
      "description": "Produção"
    }
  ],
  "security": [
    {
      "ChaveApi": []
    }
  ],
  "tags": [
    {
      "name": "Números",
      "description": "Consultar números, conectar por QR Code ou código de pareamento e desconectar. Criar e remover números continua no painel (ocupa uma vaga do plano e guarda credenciais)."
    },
    {
      "name": "Mensagens",
      "description": "Envio individual de texto, mídia (por URL HTTPS) e template, e consulta de mensagens e conversas."
    },
    {
      "name": "Contatos e configurações",
      "description": "Números não oficiais: verificar se telefones têm WhatsApp, foto e recado do contato, bloqueio, agenda, perfil, privacidade, configurações do número, organizar conversas, histórico e rejeitar chamadas. No oficial, só o recado do perfil comercial."
    },
    {
      "name": "Grupos",
      "description": "Números não oficiais: listar, criar e administrar grupos, convites, entrar e sair. Para mandar mensagem ao grupo, use `grupoId` nos envios. Receber mensagens de grupo exige `ignorarGrupos: false` nas configurações do número. Grupos não geram lead, não disparam resposta automática nem opt-out e não entram na economia."
    },
    {
      "name": "Comunidades e canais",
      "description": "Números não oficiais: criar comunidades e juntar grupos a elas; criar canais (newsletter), listar os que o número segue, ver detalhes, abrir um link de convite e ler as publicações. Nada disso é guardado no ZapHub. Seguir um canal pelo link não está disponível (o Evolution não tem essa ação)."
    },
    {
      "name": "Templates e campanhas",
      "description": "Templates aprovados do número oficial e campanhas em massa (somente números OFICIAL)."
    },
    {
      "name": "Leads",
      "description": "Leads captados pelo número oficial e seu repasse a números não oficiais."
    },
    {
      "name": "Economia",
      "description": "Quanto o cliente economiza em Marketing e Utility usando números não oficiais."
    },
    {
      "name": "Destinos de eventos",
      "description": "Onde o ZapHub entrega os eventos: webhook HTTPS assinado, RabbitMQ (exchange ou uma fila por evento), NATS, Kafka ou Amazon SQS do próprio cliente."
    },
    {
      "name": "Eventos ao vivo",
      "description": "Catálogo de eventos e WebSocket (`wss://…/v1/eventos/ws`) para receber eventos em tempo real, com retomada por `desde`."
    },
    {
      "name": "Eventos",
      "description": "Eventos entregues por webhook, RabbitMQ, NATS, Kafka, SQS ou WebSocket (não são endpoints da API)."
    }
  ],
  "components": {
    "securitySchemes": {
      "ChaveApi": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "zh_live_…",
        "description": "Chave de API da conta (`zh_live_…`), criada no painel. Envie `Authorization: Bearer <chave>`. A chave é exibida uma única vez na criação e pode ser restrita a um subconjunto de números."
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "description": "Limite da chave por minuto (600).",
        "schema": {
          "type": "string"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Requisições restantes na janela.",
        "schema": {
          "type": "string"
        }
      },
      "X-RateLimit-Reset": {
        "description": "Instante (epoch, segundos) em que a próxima vaga abre.",
        "schema": {
          "type": "string"
        }
      },
      "Retry-After": {
        "description": "Segundos até poder tentar de novo.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Erro400": {
        "description": "Dados inválidos. `fields` indica o que corrigir.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro401": {
        "description": "Chave de API ausente, inválida ou revogada.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro402": {
        "description": "A assinatura da conta está inativa (suspensa ou cancelada). Regularize o pagamento.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro403": {
        "description": "A chave é restrita a números e este recurso está fora do conjunto dela.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro404": {
        "description": "Recurso inexistente ou de outra conta.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro409": {
        "description": "Conflito com o estado atual do recurso.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro422": {
        "description": "Regra de negócio ou dado que o ZapHub recusa (o `code` diz qual).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      },
      "Erro429": {
        "description": "Limite de requisições por minuto da chave excedido. Aguarde `Retry-After` segundos.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        }
      },
      "Erro502": {
        "description": "O WhatsApp (Evolution ou Meta) recusou a operação. O `code` e a mensagem são os do canal; nada foi alterado.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        }
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer"
          },
          "code": {
            "type": "string",
            "description": "Código estável (ex.: `nao_encontrado`, `campanha_exige_api_oficial`). Ramifique por ele."
          },
          "message": {
            "type": "string",
            "description": "Texto em português para humanos. Não ramifique por ele."
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Erros por campo, quando a validação falha."
          }
        },
        "required": [
          "statusCode",
          "code",
          "message"
        ],
        "description": "Formato de TODO erro da API."
      },
      "Numero": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "tipo": {
            "type": "string",
            "enum": [
              "OFICIAL",
              "NAO_OFICIAL"
            ]
          },
          "apelido": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "DESCONECTADO",
              "CONECTANDO",
              "CONECTADO",
              "ERRO",
              "AGUARDANDO_WEBHOOK",
              "ATIVO",
              "RESTRITO",
              "DESATIVADO",
              "REMOCAO_PENDENTE"
            ]
          },
          "telefone": {
            "type": [
              "string",
              "null"
            ],
            "description": "E.164 sem `+`. Nulo até conectar (não oficial) ou validar (oficial)."
          },
          "nomePerfil": {
            "type": [
              "string",
              "null"
            ]
          },
          "ritmoPorMinuto": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Só NAO_OFICIAL: cadência de saída (mensagens/minuto)."
          },
          "criadoEm": {
            "type": "string"
          },
          "ultimaAtividadeEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "oficial": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "qualityRating": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "nomeVerificado": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "alertaPagamento": {
                "type": "boolean"
              },
              "statusMotivo": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "vazaoPorSegundo": {
                "type": "integer"
              }
            },
            "required": [
              "qualityRating",
              "nomeVerificado",
              "alertaPagamento",
              "statusMotivo",
              "vazaoPorSegundo"
            ]
          },
          "naoOficial": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "conectadoEm": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "protegidoPorProxy": {
                "type": "boolean"
              }
            },
            "required": [
              "conectadoEm",
              "protegidoPorProxy"
            ]
          },
          "indicadores": {
            "type": "object",
            "properties": {
              "numeroId": {
                "type": "string"
              },
              "tipo": {
                "type": "string",
                "enum": [
                  "OFICIAL",
                  "NAO_OFICIAL"
                ]
              },
              "geradoEm": {
                "type": "string"
              },
              "iniciosConversa": {
                "type": "object",
                "properties": {
                  "ultimaHora": {
                    "type": "integer"
                  },
                  "hoje": {
                    "type": "integer"
                  }
                },
                "required": [
                  "ultimaHora",
                  "hoje"
                ]
              },
              "mensagensEnviadas": {
                "type": "object",
                "properties": {
                  "ultimaHora": {
                    "type": "integer"
                  },
                  "hoje": {
                    "type": "integer"
                  }
                },
                "required": [
                  "ultimaHora",
                  "hoje"
                ]
              },
              "desconexoes": {
                "type": "object",
                "properties": {
                  "ultimas24h": {
                    "type": "integer"
                  },
                  "ultimaEm": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "ultimas24h",
                  "ultimaEm"
                ]
              },
              "ritmoPorMinuto": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "naFila": {
                "type": "integer"
              }
            },
            "required": [
              "numeroId",
              "tipo",
              "geradoEm",
              "iniciosConversa",
              "mensagensEnviadas",
              "desconexoes",
              "ritmoPorMinuto",
              "naFila"
            ],
            "description": "Só em `GET /v1/numeros/{id}`."
          },
          "recursos": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "envio.texto",
                "envio.midia",
                "envio.localizacao",
                "envio.contato",
                "envio.figurinha",
                "envio.enquete",
                "envio.template",
                "envio.interativo",
                "envio.citacao",
                "envio.mencao",
                "envio.previaLink",
                "operacao.reacao",
                "operacao.lida",
                "operacao.digitando",
                "operacao.editar",
                "operacao.apagar",
                "contatos.verificar",
                "contatos.info",
                "contatos.bloquear",
                "numero.agenda",
                "numero.perfil",
                "numero.privacidade",
                "numero.configuracoes",
                "conversa.organizar",
                "historico.sincronizar",
                "chamada.rejeitar",
                "grupos",
                "numero.status",
                "etiquetas",
                "comunidades",
                "canais"
              ]
            },
            "description": "O que o número suporta, conforme o tipo. Rota fora da lista responde 422 `recurso_indisponivel`."
          }
        },
        "required": [
          "id",
          "tipo",
          "apelido",
          "status",
          "telefone",
          "nomePerfil",
          "ritmoPorMinuto",
          "criadoEm",
          "ultimaAtividadeEm",
          "oficial",
          "naoOficial",
          "recursos"
        ]
      },
      "ResultadoEnvio": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador da mensagem (`GET /v1/mensagens/{id}`). O resultado final chega em `mensagem.status`."
          },
          "tipoNumero": {
            "type": "string",
            "enum": [
              "OFICIAL",
              "NAO_OFICIAL"
            ]
          },
          "tipoEnvio": {
            "type": "string",
            "enum": [
              "PRIMEIRO_CONTATO",
              "PRIMEIRA_RESPOSTA",
              "CONVERSA",
              "RETOMADA",
              "CONTATO_LEAD",
              "AUTO_RESPOSTA",
              "CAMPANHA",
              "GRUPO"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ENFILEIRADA",
              "ENVIADA",
              "ENTREGUE",
              "LIDA",
              "FALHOU",
              "RECEBIDA"
            ]
          },
          "enfileirada": {
            "type": "boolean",
            "description": "true = na fila de cadência do número (não oficial); sai logo em seguida."
          },
          "custoEvitado": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "marketingCentavos": {
                "type": "integer"
              },
              "utilityCentavos": {
                "type": "integer"
              }
            },
            "required": [
              "marketingCentavos",
              "utilityCentavos"
            ],
            "description": "Só números NAO_OFICIAL: quanto custaria a mesma mensagem na API Oficial."
          },
          "contatoOptout": {
            "type": "boolean",
            "description": "O contato pediu para sair; o envio não é bloqueado, só sinalizado."
          },
          "janelaAberta": {
            "type": "boolean",
            "description": "Janela de 24h aberta (informativo)."
          },
          "erro": {
            "type": "object",
            "properties": {
              "codigo": {
                "type": "string"
              },
              "codigoExterno": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mensagem": {
                "type": "string"
              }
            },
            "required": [
              "codigo",
              "codigoExterno",
              "mensagem"
            ],
            "description": "Só com `status: FALHOU`: o erro do canal (na Meta, com o código dela)."
          },
          "custoEstimado": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "categoria": {
                "type": "string",
                "enum": [
                  "MARKETING",
                  "UTILITY",
                  "AUTHENTICATION"
                ]
              },
              "centavos": {
                "type": "integer",
                "description": "Estimativa do que a Meta cobra por esta mensagem, em centavos de BRL."
              },
              "precoUsd": {
                "type": "string"
              },
              "cambio": {
                "type": "string"
              },
              "tabelaVersao": {
                "type": "integer"
              },
              "estimado": {
                "type": "boolean",
                "enum": [
                  true
                ]
              }
            },
            "required": [
              "categoria",
              "centavos",
              "precoUsd",
              "cambio",
              "tabelaVersao",
              "estimado"
            ],
            "description": "Só em templates: estimativa pela tabela pública."
          }
        },
        "required": [
          "id",
          "tipoNumero",
          "tipoEnvio",
          "status",
          "enfileirada",
          "custoEvitado",
          "contatoOptout",
          "janelaAberta"
        ]
      },
      "Mensagem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "numeroId": {
            "type": "string"
          },
          "tipoNumero": {
            "type": "string",
            "enum": [
              "OFICIAL",
              "NAO_OFICIAL"
            ]
          },
          "conversaId": {
            "type": "string"
          },
          "contato": {
            "type": "object",
            "properties": {
              "telefone": {
                "type": "string"
              }
            },
            "required": [
              "telefone"
            ]
          },
          "direcao": {
            "type": "string",
            "enum": [
              "ENTRADA",
              "SAIDA"
            ]
          },
          "origem": {
            "type": "string",
            "enum": [
              "CONTATO",
              "CELULAR",
              "PAINEL",
              "API",
              "AUTO",
              "CAMPANHA",
              "REPASSE"
            ]
          },
          "tipoEnvio": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "PRIMEIRO_CONTATO",
              "PRIMEIRA_RESPOSTA",
              "CONVERSA",
              "RETOMADA",
              "CONTATO_LEAD",
              "AUTO_RESPOSTA",
              "CAMPANHA",
              "GRUPO"
            ]
          },
          "tipoConteudo": {
            "type": "string",
            "enum": [
              "TEXTO",
              "IMAGEM",
              "AUDIO",
              "VIDEO",
              "DOCUMENTO",
              "LOCALIZACAO",
              "TEMPLATE",
              "CONTATO",
              "FIGURINHA",
              "ENQUETE",
              "OUTRO"
            ]
          },
          "texto": {
            "type": [
              "string",
              "null"
            ],
            "description": "Nulo depois da retenção (`removida`)."
          },
          "midia": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "tipo": {
                "type": "string",
                "enum": [
                  "IMAGEM",
                  "AUDIO",
                  "VIDEO",
                  "DOCUMENTO"
                ]
              },
              "mimeType": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "disponivel": {
                "type": "boolean"
              }
            },
            "required": [
              "tipo",
              "mimeType",
              "disponivel"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ENFILEIRADA",
              "ENVIADA",
              "ENTREGUE",
              "LIDA",
              "FALHOU",
              "RECEBIDA"
            ]
          },
          "enfileirada": {
            "type": "boolean"
          },
          "contatoOptout": {
            "type": "boolean"
          },
          "custoEvitado": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "marketingCentavos": {
                "type": "integer"
              },
              "utilityCentavos": {
                "type": "integer"
              }
            },
            "required": [
              "marketingCentavos",
              "utilityCentavos"
            ]
          },
          "erro": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "codigo": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mensagem": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "codigo",
              "mensagem"
            ]
          },
          "criadoEm": {
            "type": "string"
          },
          "enviadoEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "entregueEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "lidoEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "removida": {
            "type": "boolean",
            "description": "Conteúdo removido pela retenção de 90 dias; os metadados permanecem."
          },
          "editadaEm": {
            "type": [
              "string",
              "null"
            ],
            "description": "O autor editou a mensagem (o texto já é o novo)."
          },
          "apagadaEm": {
            "type": [
              "string",
              "null"
            ],
            "description": "O autor apagou para todos: texto e mídia foram limpos."
          },
          "reacoes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "autor": {
                  "type": "string",
                  "enum": [
                    "contato",
                    "numero"
                  ]
                },
                "emoji": {
                  "type": "string"
                }
              },
              "required": [
                "autor",
                "emoji"
              ]
            },
            "description": "Reação atual de cada lado."
          },
          "contatos": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "properties": {
                "nome": {
                  "type": "string"
                },
                "telefones": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "empresa": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                }
              },
              "required": [
                "nome",
                "telefones"
              ]
            },
            "description": "Só em `tipoConteudo: CONTATO`."
          },
          "enquete": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "maxRespostas": {
                "type": "integer"
              },
              "opcoes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "opcao": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "opcao",
                    "total"
                  ]
                }
              }
            },
            "required": [
              "maxRespostas",
              "opcoes"
            ],
            "description": "Só em enquetes enviadas pelo número; o detalhe por contato está em `GET /v1/mensagens/{id}/votos`."
          },
          "respondendoA": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "trecho": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "trecho"
            ],
            "description": "Mensagem citada."
          },
          "remetente": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "telefone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "nome": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "telefone",
              "nome"
            ],
            "description": "Só em grupo: quem escreveu."
          },
          "interativo": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "tipo": {
                "type": "string",
                "enum": [
                  "botoes",
                  "lista",
                  "link"
                ]
              },
              "opcoes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "tipo",
              "opcoes"
            ],
            "description": "Mensagem interativa enviada (oficial): o tipo e os títulos das opções."
          },
          "interacao": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "tipo": {
                "type": "string",
                "enum": [
                  "botao",
                  "lista"
                ]
              },
              "id": {
                "type": "string"
              },
              "titulo": {
                "type": "string"
              }
            },
            "required": [
              "tipo",
              "id",
              "titulo"
            ],
            "description": "Resposta do contato a uma interativa: o botão ou item escolhido."
          }
        },
        "required": [
          "id",
          "numeroId",
          "tipoNumero",
          "conversaId",
          "contato",
          "direcao",
          "origem",
          "tipoEnvio",
          "tipoConteudo",
          "texto",
          "midia",
          "status",
          "enfileirada",
          "contatoOptout",
          "custoEvitado",
          "erro",
          "criadoEm",
          "enviadoEm",
          "entregueEm",
          "lidoEm",
          "removida",
          "editadaEm",
          "apagadaEm",
          "reacoes",
          "contatos",
          "enquete",
          "respondendoA",
          "remetente",
          "interativo",
          "interacao"
        ]
      },
      "Campanha": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "nome": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "RASCUNHO",
              "AGENDADA",
              "EM_ANDAMENTO",
              "PAUSADA",
              "PAUSADA_AUTOMATICAMENTE",
              "CONCLUIDA",
              "CANCELADA"
            ]
          },
          "numero": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "apelido": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "apelido"
            ]
          },
          "template": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "nome": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "nome"
            ]
          },
          "lista": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "nome": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "nome"
            ]
          },
          "agendadaPara": {
            "type": [
              "string",
              "null"
            ]
          },
          "iniciadaEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "concluidaEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "pausaAutomatica": {
            "type": "boolean"
          },
          "motivoPausa": {
            "type": [
              "string",
              "null"
            ]
          },
          "custoEstimadoCentavos": {
            "type": "integer"
          },
          "total": {
            "type": "integer",
            "description": "Contatos da campanha."
          },
          "totais": {
            "type": "object",
            "properties": {
              "pendente": {
                "type": "integer"
              },
              "enviado": {
                "type": "integer"
              },
              "entregue": {
                "type": "integer"
              },
              "lido": {
                "type": "integer"
              },
              "respondido": {
                "type": "integer"
              },
              "falhou": {
                "type": "integer"
              },
              "ignoradoOptout": {
                "type": "integer"
              }
            },
            "required": [
              "pendente",
              "enviado",
              "entregue",
              "lido",
              "respondido",
              "falhou",
              "ignoradoOptout"
            ]
          },
          "alertas": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "codigo": {
                  "type": "string"
                },
                "mensagem": {
                  "type": "string"
                }
              },
              "required": [
                "codigo",
                "mensagem"
              ]
            },
            "description": "Informativos; nunca bloqueiam."
          },
          "taxaFalha": {
            "type": "number",
            "description": "Falhas ÷ (enviados + falhas), em %."
          },
          "erroMaisFrequente": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "codigo": {
                "type": "string"
              },
              "mensagem": {
                "type": "string"
              },
              "quantidade": {
                "type": "integer"
              }
            },
            "required": [
              "codigo",
              "mensagem",
              "quantidade"
            ]
          },
          "criadoEm": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "nome",
          "status",
          "numero",
          "template",
          "lista",
          "agendadaPara",
          "iniciadaEm",
          "concluidaEm",
          "pausaAutomatica",
          "motivoPausa",
          "custoEstimadoCentavos",
          "total",
          "totais",
          "alertas",
          "taxaFalha",
          "erroMaisFrequente",
          "criadoEm"
        ]
      },
      "Lead": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "contatoTelefone": {
            "type": "string"
          },
          "contatoNome": {
            "type": [
              "string",
              "null"
            ]
          },
          "origem": {
            "type": "string",
            "enum": [
              "CAMPANHA",
              "ANUNCIO",
              "ORGANICO"
            ]
          },
          "campanha": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "nome": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "nome"
            ]
          },
          "anuncio": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "titulo": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "titulo",
              "url"
            ]
          },
          "primeiraMensagem": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "NOVO",
              "REPASSADO",
              "EM_CONTATO",
              "RESPONDEU",
              "SEM_RESPOSTA",
              "DESCARTADO"
            ]
          },
          "numeroOficial": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "apelido": {
                "type": "string"
              },
              "telefone": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "apelido",
              "telefone"
            ]
          },
          "numeroAtribuido": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "apelido": {
                "type": "string"
              },
              "telefone": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "apelido",
              "telefone"
            ]
          },
          "conversaId": {
            "type": [
              "string",
              "null"
            ]
          },
          "contatoOptout": {
            "type": "boolean"
          },
          "repassadoEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "respondeuEm": {
            "type": [
              "string",
              "null"
            ]
          },
          "criadoEm": {
            "type": "string"
          },
          "economia": {
            "type": "object",
            "properties": {
              "qtd": {
                "type": "integer"
              },
              "marketingCentavos": {
                "type": "integer"
              },
              "utilityCentavos": {
                "type": "integer"
              }
            },
            "required": [
              "qtd",
              "marketingCentavos",
              "utilityCentavos"
            ]
          }
        },
        "required": [
          "id",
          "contatoTelefone",
          "contatoNome",
          "origem",
          "campanha",
          "anuncio",
          "primeiraMensagem",
          "status",
          "numeroOficial",
          "numeroAtribuido",
          "conversaId",
          "contatoOptout",
          "repassadoEm",
          "respondeuEm",
          "criadoEm",
          "economia"
        ]
      },
      "DestinoEvento": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "tipo": {
            "type": "string",
            "enum": [
              "WEBHOOK",
              "RABBITMQ",
              "NATS",
              "KAFKA",
              "SQS"
            ]
          },
          "nome": {
            "type": "string"
          },
          "ativo": {
            "type": "boolean"
          },
          "eventos": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mensagem.recebida",
                "mensagem.enviada",
                "mensagem.status",
                "numero.status",
                "numero.qrcode",
                "contato.optout",
                "campanha.status",
                "lead.criado",
                "lead.repassado",
                "lead.status",
                "mensagem.reacao",
                "mensagem.editada",
                "mensagem.apagada",
                "mensagem.voto",
                "contato.digitando",
                "contato.presenca",
                "contato.atualizado",
                "chamada.recebida",
                "chamada.encerrada",
                "numero.banido",
                "historico.sincronizado",
                "grupo.atualizado",
                "grupo.participantes",
                "grupo.entrou",
                "etiqueta.alterada",
                "etiqueta.aplicada",
                "canal.seguido",
                "canal.deixado",
                "evolution.bruto"
              ]
            }
          },
          "numeroIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Vazio = todos os números."
          },
          "config": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  }
                },
                "required": [
                  "url"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "host": {
                    "type": "string"
                  },
                  "port": {
                    "type": "integer"
                  },
                  "vhost": {
                    "type": "string"
                  },
                  "usuario": {
                    "type": "string",
                    "description": "Mascarado."
                  },
                  "senha": {
                    "type": "string",
                    "description": "Sempre mascarada."
                  },
                  "exchange": {
                    "type": "string"
                  },
                  "prefixo": {
                    "type": "string"
                  },
                  "tls": {
                    "type": "boolean"
                  },
                  "permitirSemTls": {
                    "type": "boolean"
                  },
                  "modo": {
                    "type": "string",
                    "enum": [
                      "exchange",
                      "filas"
                    ]
                  }
                },
                "required": [
                  "host",
                  "port",
                  "vhost",
                  "usuario",
                  "senha",
                  "exchange",
                  "prefixo",
                  "tls",
                  "permitirSemTls",
                  "modo"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "servidores": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "tls": {
                    "type": "boolean"
                  },
                  "permitirSemTls": {
                    "type": "boolean"
                  },
                  "autenticacao": {
                    "type": "string",
                    "enum": [
                      "nenhuma",
                      "token",
                      "usuario",
                      "creds"
                    ]
                  },
                  "usuario": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Mascarado."
                  },
                  "senha": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Sempre mascarada."
                  },
                  "prefixo": {
                    "type": "string"
                  },
                  "jetstream": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "servidores",
                  "tls",
                  "permitirSemTls",
                  "autenticacao",
                  "usuario",
                  "senha",
                  "prefixo",
                  "jetstream"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "brokers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "tls": {
                    "type": "boolean"
                  },
                  "permitirSemTls": {
                    "type": "boolean"
                  },
                  "sasl": {
                    "type": "string",
                    "enum": [
                      "nenhum",
                      "plain",
                      "scram-sha-256",
                      "scram-sha-512"
                    ]
                  },
                  "usuario": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Mascarado."
                  },
                  "senha": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Sempre mascarada."
                  },
                  "topico": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "prefixoTopico": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "brokers",
                  "tls",
                  "permitirSemTls",
                  "sasl",
                  "usuario",
                  "senha",
                  "topico",
                  "prefixoTopico"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "filaUrl": {
                    "type": "string"
                  },
                  "regiao": {
                    "type": "string"
                  },
                  "fifo": {
                    "type": "boolean"
                  },
                  "accessKeyId": {
                    "type": "string",
                    "description": "Mascarado."
                  },
                  "secretAccessKey": {
                    "type": "string",
                    "description": "Sempre mascarado."
                  }
                },
                "required": [
                  "filaUrl",
                  "regiao",
                  "fifo",
                  "accessKeyId",
                  "secretAccessKey"
                ]
              }
            ]
          },
          "segredoHmac": {
            "type": "string",
            "description": "Segredo de assinatura MASCARADO. O completo só aparece na criação/rotação."
          },
          "criadoEm": {
            "type": "string"
          },
          "atualizadoEm": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "tipo",
          "nome",
          "ativo",
          "eventos",
          "numeroIds",
          "config",
          "segredoHmac",
          "criadoEm",
          "atualizadoEm"
        ]
      },
      "EnvelopeEvento": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Único. Use para deduplicar (o mesmo evento vai com o mesmo `id` para todos os destinos e em cada nova tentativa)."
          },
          "evento": {
            "type": "string",
            "enum": [
              "mensagem.recebida",
              "mensagem.enviada",
              "mensagem.status",
              "numero.status",
              "numero.qrcode",
              "contato.optout",
              "campanha.status",
              "lead.criado",
              "lead.repassado",
              "lead.status",
              "mensagem.reacao",
              "mensagem.editada",
              "mensagem.apagada",
              "mensagem.voto",
              "contato.digitando",
              "contato.presenca",
              "contato.atualizado",
              "chamada.recebida",
              "chamada.encerrada",
              "numero.banido",
              "historico.sincronizado",
              "grupo.atualizado",
              "grupo.participantes",
              "grupo.entrou",
              "etiqueta.alterada",
              "etiqueta.aplicada",
              "canal.seguido",
              "canal.deixado",
              "evolution.bruto"
            ]
          },
          "ocorridoEm": {
            "type": "string"
          },
          "contaId": {
            "type": "string"
          },
          "numeroId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Nulo em eventos sem número."
          },
          "sequencia": {
            "type": "integer",
            "description": "Crescente por número: use para reordenar. Zero em eventos sem número."
          },
          "dados": {
            "type": "object",
            "additionalProperties": {},
            "description": "Varia por evento (ver cada evento)."
          }
        },
        "required": [
          "id",
          "evento",
          "ocorridoEm",
          "contaId",
          "numeroId",
          "sequencia",
          "dados"
        ],
        "description": "Envelope comum a TODOS os eventos, em webhook e em RabbitMQ."
      }
    },
    "parameters": {}
  },
  "paths": {
    "/v1/numeros": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarNumeros",
        "tags": [
          "Números"
        ],
        "summary": "Lista os números",
        "description": "Números da conta (ou do conjunto permitido da chave). Token e credenciais da Meta nunca saem.",
        "responses": {
          "200": {
            "description": "Lista de números.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "numeros": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "tipo": {
                            "type": "string",
                            "enum": [
                              "OFICIAL",
                              "NAO_OFICIAL"
                            ]
                          },
                          "apelido": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "DESCONECTADO",
                              "CONECTANDO",
                              "CONECTADO",
                              "ERRO",
                              "AGUARDANDO_WEBHOOK",
                              "ATIVO",
                              "RESTRITO",
                              "DESATIVADO",
                              "REMOCAO_PENDENTE"
                            ]
                          },
                          "telefone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "E.164 sem `+`. Nulo até conectar (não oficial) ou validar (oficial)."
                          },
                          "nomePerfil": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ritmoPorMinuto": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Só NAO_OFICIAL: cadência de saída (mensagens/minuto)."
                          },
                          "criadoEm": {
                            "type": "string"
                          },
                          "ultimaAtividadeEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "oficial": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "qualityRating": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "nomeVerificado": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "alertaPagamento": {
                                "type": "boolean"
                              },
                              "statusMotivo": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "vazaoPorSegundo": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "qualityRating",
                              "nomeVerificado",
                              "alertaPagamento",
                              "statusMotivo",
                              "vazaoPorSegundo"
                            ]
                          },
                          "naoOficial": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "conectadoEm": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "protegidoPorProxy": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "conectadoEm",
                              "protegidoPorProxy"
                            ]
                          },
                          "indicadores": {
                            "type": "object",
                            "properties": {
                              "numeroId": {
                                "type": "string"
                              },
                              "tipo": {
                                "type": "string",
                                "enum": [
                                  "OFICIAL",
                                  "NAO_OFICIAL"
                                ]
                              },
                              "geradoEm": {
                                "type": "string"
                              },
                              "iniciosConversa": {
                                "type": "object",
                                "properties": {
                                  "ultimaHora": {
                                    "type": "integer"
                                  },
                                  "hoje": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "ultimaHora",
                                  "hoje"
                                ]
                              },
                              "mensagensEnviadas": {
                                "type": "object",
                                "properties": {
                                  "ultimaHora": {
                                    "type": "integer"
                                  },
                                  "hoje": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "ultimaHora",
                                  "hoje"
                                ]
                              },
                              "desconexoes": {
                                "type": "object",
                                "properties": {
                                  "ultimas24h": {
                                    "type": "integer"
                                  },
                                  "ultimaEm": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "ultimas24h",
                                  "ultimaEm"
                                ]
                              },
                              "ritmoPorMinuto": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "naFila": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "numeroId",
                              "tipo",
                              "geradoEm",
                              "iniciosConversa",
                              "mensagensEnviadas",
                              "desconexoes",
                              "ritmoPorMinuto",
                              "naFila"
                            ],
                            "description": "Só em `GET /v1/numeros/{id}`."
                          },
                          "recursos": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "envio.texto",
                                "envio.midia",
                                "envio.localizacao",
                                "envio.contato",
                                "envio.figurinha",
                                "envio.enquete",
                                "envio.template",
                                "envio.interativo",
                                "envio.citacao",
                                "envio.mencao",
                                "envio.previaLink",
                                "operacao.reacao",
                                "operacao.lida",
                                "operacao.digitando",
                                "operacao.editar",
                                "operacao.apagar",
                                "contatos.verificar",
                                "contatos.info",
                                "contatos.bloquear",
                                "numero.agenda",
                                "numero.perfil",
                                "numero.privacidade",
                                "numero.configuracoes",
                                "conversa.organizar",
                                "historico.sincronizar",
                                "chamada.rejeitar",
                                "grupos",
                                "numero.status",
                                "etiquetas",
                                "comunidades",
                                "canais"
                              ]
                            },
                            "description": "O que o número suporta, conforme o tipo. Rota fora da lista responde 422 `recurso_indisponivel`."
                          }
                        },
                        "required": [
                          "id",
                          "tipo",
                          "apelido",
                          "status",
                          "telefone",
                          "nomePerfil",
                          "ritmoPorMinuto",
                          "criadoEm",
                          "ultimaAtividadeEm",
                          "oficial",
                          "naoOficial",
                          "recursos"
                        ]
                      }
                    }
                  },
                  "required": [
                    "numeros"
                  ]
                },
                "example": {
                  "numeros": [
                    {
                      "id": "clx0numero000000000000001",
                      "tipo": "NAO_OFICIAL",
                      "apelido": "Vendas",
                      "status": "CONECTADO",
                      "telefone": "5511987654321",
                      "nomePerfil": "Loja Exemplo",
                      "ritmoPorMinuto": 120,
                      "criadoEm": "2026-10-01T12:00:00.000Z",
                      "ultimaAtividadeEm": "2026-10-14T13:00:00.000Z",
                      "oficial": null,
                      "naoOficial": {
                        "conectadoEm": "2026-10-01T12:05:00.000Z"
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/numeros/{id}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterNumero",
        "tags": [
          "Números"
        ],
        "summary": "Detalhe de um número",
        "description": "Tipo, telefone, status e `indicadores` informativos (inícios de conversa, mensagens enviadas, desconexões e fila). Os indicadores nunca bloqueiam nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador público do número."
            },
            "required": true,
            "description": "Identificador público do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O número.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Numero"
                },
                "example": {
                  "id": "clx0numero000000000000001",
                  "tipo": "NAO_OFICIAL",
                  "apelido": "Vendas",
                  "status": "CONECTADO",
                  "telefone": "5511987654321",
                  "nomePerfil": "Loja Exemplo",
                  "ritmoPorMinuto": 120,
                  "criadoEm": "2026-10-01T12:00:00.000Z",
                  "ultimaAtividadeEm": "2026-10-14T13:00:00.000Z",
                  "oficial": null,
                  "naoOficial": {
                    "conectadoEm": "2026-10-01T12:05:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/numeros/{id}/conectar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "conectarNumero",
        "tags": [
          "Números"
        ],
        "summary": "Conecta um número não oficial (QR ou código)",
        "description": "Somente `NAO_OFICIAL`; em número `OFICIAL` responde 422. Sem corpo devolve o QR atual (imagem base64 e texto). Com `{\"telefone\": \"...\"}` devolve o código de pareamento de 8 caracteres. Os QRs renovados chegam pelo evento `numero.qrcode` e o evento `numero.status` com `CONECTADO` confirma o pareamento.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador público do número."
            },
            "required": true,
            "description": "Identificador público do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "telefone": {
                    "type": "string",
                    "description": "Com telefone, devolve o código de pareamento de 8 caracteres em vez do QR."
                  }
                }
              },
              "example": {
                "telefone": "5511987654321"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "QR ou código de pareamento.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "numero": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "tipo": {
                          "type": "string",
                          "enum": [
                            "OFICIAL",
                            "NAO_OFICIAL"
                          ]
                        },
                        "apelido": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "DESCONECTADO",
                            "CONECTANDO",
                            "CONECTADO",
                            "ERRO",
                            "AGUARDANDO_WEBHOOK",
                            "ATIVO",
                            "RESTRITO",
                            "DESATIVADO",
                            "REMOCAO_PENDENTE"
                          ]
                        },
                        "telefone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "E.164 sem `+`. Nulo até conectar (não oficial) ou validar (oficial)."
                        },
                        "nomePerfil": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "ritmoPorMinuto": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Só NAO_OFICIAL: cadência de saída (mensagens/minuto)."
                        },
                        "criadoEm": {
                          "type": "string"
                        },
                        "ultimaAtividadeEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "oficial": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "qualityRating": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "nomeVerificado": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "alertaPagamento": {
                              "type": "boolean"
                            },
                            "statusMotivo": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "vazaoPorSegundo": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "qualityRating",
                            "nomeVerificado",
                            "alertaPagamento",
                            "statusMotivo",
                            "vazaoPorSegundo"
                          ]
                        },
                        "naoOficial": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "conectadoEm": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "protegidoPorProxy": {
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "conectadoEm",
                            "protegidoPorProxy"
                          ]
                        },
                        "indicadores": {
                          "type": "object",
                          "properties": {
                            "numeroId": {
                              "type": "string"
                            },
                            "tipo": {
                              "type": "string",
                              "enum": [
                                "OFICIAL",
                                "NAO_OFICIAL"
                              ]
                            },
                            "geradoEm": {
                              "type": "string"
                            },
                            "iniciosConversa": {
                              "type": "object",
                              "properties": {
                                "ultimaHora": {
                                  "type": "integer"
                                },
                                "hoje": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "ultimaHora",
                                "hoje"
                              ]
                            },
                            "mensagensEnviadas": {
                              "type": "object",
                              "properties": {
                                "ultimaHora": {
                                  "type": "integer"
                                },
                                "hoje": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "ultimaHora",
                                "hoje"
                              ]
                            },
                            "desconexoes": {
                              "type": "object",
                              "properties": {
                                "ultimas24h": {
                                  "type": "integer"
                                },
                                "ultimaEm": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                }
                              },
                              "required": [
                                "ultimas24h",
                                "ultimaEm"
                              ]
                            },
                            "ritmoPorMinuto": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "naFila": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "numeroId",
                            "tipo",
                            "geradoEm",
                            "iniciosConversa",
                            "mensagensEnviadas",
                            "desconexoes",
                            "ritmoPorMinuto",
                            "naFila"
                          ],
                          "description": "Só em `GET /v1/numeros/{id}`."
                        },
                        "recursos": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "envio.texto",
                              "envio.midia",
                              "envio.localizacao",
                              "envio.contato",
                              "envio.figurinha",
                              "envio.enquete",
                              "envio.template",
                              "envio.interativo",
                              "envio.citacao",
                              "envio.mencao",
                              "envio.previaLink",
                              "operacao.reacao",
                              "operacao.lida",
                              "operacao.digitando",
                              "operacao.editar",
                              "operacao.apagar",
                              "contatos.verificar",
                              "contatos.info",
                              "contatos.bloquear",
                              "numero.agenda",
                              "numero.perfil",
                              "numero.privacidade",
                              "numero.configuracoes",
                              "conversa.organizar",
                              "historico.sincronizar",
                              "chamada.rejeitar",
                              "grupos",
                              "numero.status",
                              "etiquetas",
                              "comunidades",
                              "canais"
                            ]
                          },
                          "description": "O que o número suporta, conforme o tipo. Rota fora da lista responde 422 `recurso_indisponivel`."
                        }
                      },
                      "required": [
                        "id",
                        "tipo",
                        "apelido",
                        "status",
                        "telefone",
                        "nomePerfil",
                        "ritmoPorMinuto",
                        "criadoEm",
                        "ultimaAtividadeEm",
                        "oficial",
                        "naoOficial",
                        "recursos"
                      ]
                    },
                    "modo": {
                      "type": "string",
                      "enum": [
                        "QR",
                        "CODIGO"
                      ]
                    },
                    "qrcode": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Imagem do QR (data URL PNG). Pode ser nula se o primeiro QR ainda não foi gerado: ele chega pelo evento `numero.qrcode`."
                    },
                    "codigo": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Texto do QR, para renderizar no seu sistema."
                    },
                    "codigoPareamento": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "expiraEm": {
                      "type": "string",
                      "description": "Depois disso o QR deixa de ser renovado; chame `conectar` de novo."
                    }
                  },
                  "required": [
                    "numero",
                    "modo",
                    "qrcode",
                    "codigo",
                    "codigoPareamento",
                    "expiraEm"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/numeros/{id}/desconectar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "desconectarNumero",
        "tags": [
          "Números"
        ],
        "summary": "Desconecta um número não oficial",
        "description": "Faz o logout da sessão do WhatsApp mantendo o número e a vaga do plano.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador público do número."
            },
            "required": true,
            "description": "Identificador público do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O número desconectado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Numero"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/numeros/{id}/templates": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarTemplates",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Templates do número oficial",
        "description": "Somente `OFICIAL`. Cada template traz o `id` para usar em `templateId`, o status de aprovação na Meta e a quantidade de variáveis.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador público do número OFICIAL."
            },
            "required": true,
            "description": "Identificador público do número OFICIAL.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Templates sincronizados da Meta.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "templates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Use em `templateId` (mensagens e campanhas)."
                          },
                          "nome": {
                            "type": "string"
                          },
                          "idioma": {
                            "type": "string"
                          },
                          "categoria": {
                            "type": "string",
                            "enum": [
                              "MARKETING",
                              "UTILITY",
                              "AUTHENTICATION"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "description": "Status na Meta: APPROVED, PENDING, REJECTED, PAUSED, DISABLED ou INDISPONIVEL."
                          },
                          "motivo": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "totalVariaveis": {
                            "type": "integer"
                          },
                          "variaveis": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": {}
                            }
                          },
                          "sincronizadoEm": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "idioma",
                          "categoria",
                          "status",
                          "motivo",
                          "totalVariaveis",
                          "variaveis",
                          "sincronizadoEm"
                        ]
                      }
                    }
                  },
                  "required": [
                    "templates"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/texto": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarTexto",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia texto",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "texto": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096
                  },
                  "previaLink": {
                    "type": "boolean",
                    "description": "Pede a prévia do primeiro link do texto."
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` de uma mensagem da mesma conversa: o envio sai citando ela."
                  },
                  "mencoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{8,15}$"
                    },
                    "maxItems": 50,
                    "description": "Telefones mencionados (só em grupos; em conversa individual é aceito e ignorado). Só NAO_OFICIAL."
                  },
                  "grupoId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Envia ao grupo (`id` de `GET /v1/numeros/{id}/grupos`) em vez de `para`. Só NAO_OFICIAL."
                  },
                  "mencionarTodos": {
                    "type": "boolean",
                    "description": "Só em grupo: menciona todos os participantes."
                  }
                },
                "required": [
                  "numeroId",
                  "texto"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "texto": "Olá! Seu pedido saiu para entrega."
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/midia": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarMidia",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia imagem, documento, áudio ou vídeo",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nA mídia vai por **URL HTTPS pública** (sem upload). URLs `http`, com usuário/senha, de hosts internos ou que resolvam para IP privado/loopback são recusadas com 422 `midia_url_invalida`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "tipo": {
                    "type": "string",
                    "enum": [
                      "imagem",
                      "documento",
                      "audio",
                      "video"
                    ]
                  },
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048,
                    "description": "URL HTTPS pública. http, hosts internos e IPs privados/loopback são recusados (422)."
                  },
                  "base64": {
                    "type": "string",
                    "maxLength": 23000000,
                    "description": "Conteúdo em base64 (ou data URL). Alternativa a `url`."
                  },
                  "mimeType": {
                    "type": "string",
                    "pattern": "^[a-z]+\\/[a-z0-9.+-]+$",
                    "description": "Obrigatório com `base64` (ex.: application/pdf)."
                  },
                  "legenda": {
                    "type": "string",
                    "maxLength": 1024
                  },
                  "nomeArquivo": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Nome exibido para documentos."
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` de uma mensagem da mesma conversa: o envio sai citando ela."
                  },
                  "mencoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{8,15}$"
                    },
                    "maxItems": 50,
                    "description": "Telefones mencionados (só em grupos; em conversa individual é aceito e ignorado). Só NAO_OFICIAL."
                  },
                  "grupoId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Envia ao grupo (`id` de `GET /v1/numeros/{id}/grupos`) em vez de `para`. Só NAO_OFICIAL."
                  },
                  "mencionarTodos": {
                    "type": "boolean",
                    "description": "Só em grupo: menciona todos os participantes."
                  }
                },
                "required": [
                  "numeroId",
                  "tipo"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "tipo": "documento",
                "url": "https://cdn.exemplo.com.br/proposta.pdf",
                "legenda": "Segue a proposta",
                "nomeArquivo": "proposta.pdf"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/localizacao": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarLocalizacao",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia uma localização (pin no mapa)",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nAceita `respondendoA` (cita uma mensagem da mesma conversa: 404 se ela não é da conta, 422 se é de outra conversa) e `mencoes` (só não oficial; efeito em grupos). Para grupo, envie `grupoId` no lugar de `para` (com `mencionarTodos`, se quiser): sem opt-out individual, tipo de envio `GRUPO`, fora da economia e na cadência do número.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "latitude": {
                    "type": "number",
                    "minimum": -90,
                    "maximum": 90
                  },
                  "longitude": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180
                  },
                  "nome": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "endereco": {
                    "type": "string",
                    "maxLength": 512
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` de uma mensagem da mesma conversa: o envio sai citando ela."
                  },
                  "mencoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{8,15}$"
                    },
                    "maxItems": 50,
                    "description": "Telefones mencionados (só em grupos; em conversa individual é aceito e ignorado). Só NAO_OFICIAL."
                  },
                  "grupoId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Envia ao grupo (`id` de `GET /v1/numeros/{id}/grupos`) em vez de `para`. Só NAO_OFICIAL."
                  },
                  "mencionarTodos": {
                    "type": "boolean",
                    "description": "Só em grupo: menciona todos os participantes."
                  }
                },
                "required": [
                  "numeroId",
                  "latitude",
                  "longitude"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "latitude": -20.3155,
                "longitude": -40.3128,
                "nome": "Loja Centro",
                "endereco": "Av. Princesa Isabel, 100 - Vitória/ES"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/contato": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarContato",
        "tags": [
          "Mensagens"
        ],
        "summary": "Compartilha contatos (vCard)",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nAté 10 contatos no oficial. Números não oficiais enviam **um contato por mensagem**, com o primeiro telefone dele (limite do Evolution Go). Aceita `respondendoA` (cita uma mensagem da mesma conversa: 404 se ela não é da conta, 422 se é de outra conversa) e `mencoes` (só não oficial; efeito em grupos). Para grupo, envie `grupoId` no lugar de `para` (com `mencionarTodos`, se quiser): sem opt-out individual, tipo de envio `GRUPO`, fora da economia e na cadência do número.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "contatos": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "nome": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256
                        },
                        "telefones": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "pattern": "^\\+?\\d{8,15}$"
                          },
                          "minItems": 1,
                          "maxItems": 5
                        },
                        "empresa": {
                          "type": "string",
                          "maxLength": 256
                        },
                        "email": {
                          "type": "string",
                          "maxLength": 256,
                          "format": "email"
                        }
                      },
                      "required": [
                        "nome",
                        "telefones"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 10
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` de uma mensagem da mesma conversa: o envio sai citando ela."
                  },
                  "mencoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{8,15}$"
                    },
                    "maxItems": 50,
                    "description": "Telefones mencionados (só em grupos; em conversa individual é aceito e ignorado). Só NAO_OFICIAL."
                  },
                  "grupoId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Envia ao grupo (`id` de `GET /v1/numeros/{id}/grupos`) em vez de `para`. Só NAO_OFICIAL."
                  },
                  "mencionarTodos": {
                    "type": "boolean",
                    "description": "Só em grupo: menciona todos os participantes."
                  }
                },
                "required": [
                  "numeroId",
                  "contatos"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "contatos": [
                  {
                    "nome": "Suporte Loja Centro",
                    "telefones": [
                      "5527999990000"
                    ],
                    "empresa": "Loja Centro"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/figurinha": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarFigurinha",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia uma figurinha",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nWebP por **URL HTTPS pública** (as mesmas regras da mídia). No não oficial, outras imagens são convertidas para WebP pelo Evolution. Aceita `respondendoA` (cita uma mensagem da mesma conversa: 404 se ela não é da conta, 422 se é de outra conversa) e `mencoes` (só não oficial; efeito em grupos). Para grupo, envie `grupoId` no lugar de `para` (com `mencionarTodos`, se quiser): sem opt-out individual, tipo de envio `GRUPO`, fora da economia e na cadência do número.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048,
                    "description": "URL HTTPS pública de um WebP (até 500 KB; animada até 1 MB)."
                  },
                  "base64": {
                    "type": "string",
                    "maxLength": 23000000,
                    "description": "Conteúdo em base64 (ou data URL). Alternativa a `url`."
                  },
                  "mimeType": {
                    "type": "string",
                    "pattern": "^[a-z]+\\/[a-z0-9.+-]+$",
                    "description": "Obrigatório com `base64` (ex.: application/pdf)."
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` de uma mensagem da mesma conversa: o envio sai citando ela."
                  },
                  "mencoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{8,15}$"
                    },
                    "maxItems": 50,
                    "description": "Telefones mencionados (só em grupos; em conversa individual é aceito e ignorado). Só NAO_OFICIAL."
                  },
                  "grupoId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Envia ao grupo (`id` de `GET /v1/numeros/{id}/grupos`) em vez de `para`. Só NAO_OFICIAL."
                  },
                  "mencionarTodos": {
                    "type": "boolean",
                    "description": "Só em grupo: menciona todos os participantes."
                  }
                },
                "required": [
                  "numeroId"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "url": "https://cdn.exemplo.com.br/obrigado.webp"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/interativa": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarInterativa",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia botões, lista ou link (número oficial)",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nSomente números `OFICIAL` (no não oficial, 422 `recurso_indisponivel`). `botoes`: até 3, título até 20 caracteres. `lista`: até 10 itens no total. `link`: botão com URL HTTPS. Segue a janela de 24h da Meta: fora dela, `status: FALHOU` com o erro da Meta. A escolha do contato chega em `mensagem.recebida` com `interacao` (`tipo`, `id`, `titulo`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Número OFICIAL."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "tipo": {
                    "type": "string",
                    "enum": [
                      "botoes",
                      "lista",
                      "link"
                    ]
                  },
                  "corpo": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1024
                  },
                  "cabecalho": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "rodape": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "botoes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256
                        },
                        "titulo": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 20
                        }
                      },
                      "required": [
                        "id",
                        "titulo"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 3,
                    "description": "Só em `botoes`."
                  },
                  "textoBotao": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20,
                    "description": "Em `lista` e `link`: o texto do botão."
                  },
                  "secoes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "titulo": {
                          "type": "string",
                          "maxLength": 24
                        },
                        "itens": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "titulo": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 24
                              },
                              "descricao": {
                                "type": "string",
                                "maxLength": 72
                              }
                            },
                            "required": [
                              "id",
                              "titulo"
                            ]
                          },
                          "minItems": 1
                        }
                      },
                      "required": [
                        "itens"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 10,
                    "description": "Só em `lista`: até 10 itens no total."
                  },
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri",
                    "description": "Só em `link`: URL HTTPS do botão."
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  }
                },
                "required": [
                  "numeroId",
                  "para",
                  "tipo",
                  "corpo"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "tipo": "botoes",
                "corpo": "Confirma o agendamento de amanhã às 10h?",
                "botoes": [
                  {
                    "id": "conf_sim",
                    "titulo": "Sim"
                  },
                  {
                    "id": "conf_nao",
                    "titulo": "Não"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/enquete": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarEnquete",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia uma enquete (número não oficial)",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nSomente números `NAO_OFICIAL` (no oficial responde 422 `recurso_indisponivel`). Os votos chegam em `mensagem.voto` e em `GET /v1/mensagens/{id}/votos`. Aceita `respondendoA` (cita uma mensagem da mesma conversa: 404 se ela não é da conta, 422 se é de outra conversa) e `mencoes` (só não oficial; efeito em grupos). Para grupo, envie `grupoId` no lugar de `para` (com `mencionarTodos`, se quiser): sem opt-out individual, tipo de envio `GRUPO`, fora da economia e na cadência do número.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Número NAO_OFICIAL."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "pergunta": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "opcoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "minItems": 2,
                    "maxItems": 12
                  },
                  "maxRespostas": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 1,
                    "description": "Quantas opções cada contato pode marcar."
                  },
                  "respondendoA": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` de uma mensagem da mesma conversa: o envio sai citando ela."
                  },
                  "mencoes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{8,15}$"
                    },
                    "maxItems": 50,
                    "description": "Telefones mencionados (só em grupos; em conversa individual é aceito e ignorado). Só NAO_OFICIAL."
                  },
                  "grupoId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Envia ao grupo (`id` de `GET /v1/numeros/{id}/grupos`) em vez de `para`. Só NAO_OFICIAL."
                  },
                  "mencionarTodos": {
                    "type": "boolean",
                    "description": "Só em grupo: menciona todos os participantes."
                  }
                },
                "required": [
                  "numeroId",
                  "pergunta",
                  "opcoes"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "pergunta": "Qual o melhor dia para a entrega?",
                "opcoes": [
                  "Sexta-feira",
                  "Sábado"
                ],
                "maxRespostas": 1
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  },
                  "contatoOptout": false,
                  "janelaAberta": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/template": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "enviarTemplate",
        "tags": [
          "Mensagens"
        ],
        "summary": "Envia um template (número oficial)",
        "description": "Responde **202**: a mensagem foi aceita e o resultado final chega no evento `mensagem.status`. Em número `OFICIAL` tudo é encaminhado à Meta sem bloqueio do ZapHub; se a Meta recusar (por exemplo, texto livre fora da janela de 24h), a resposta traz `status: FALHOU` e `erro` com o código e a mensagem da Meta. Em `NAO_OFICIAL` não há bloqueio por volume: acima do ritmo do número a mensagem fica `enfileirada` e sai logo em seguida.\n\nSomente números `OFICIAL`. A resposta inclui `custoEstimado` (pela tabela pública de preços da Meta e o câmbio vigente), quando a tabela está configurada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Número OFICIAL."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "templateId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` do template em `GET /v1/numeros/{id}/templates`."
                  },
                  "variaveis": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 1024
                    },
                    "maxItems": 30,
                    "default": [],
                    "description": "Valores das variáveis `{{1}}`, `{{2}}`… na ordem (cabeçalho, corpo, botões)."
                  }
                },
                "required": [
                  "numeroId",
                  "para",
                  "templateId"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "templateId": "clx0template0000000000001",
                "variaveis": [
                  "Ana",
                  "COD-1042"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem aceita.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoEnvio"
                },
                "example": {
                  "id": "clx0mensagem0000000000001",
                  "tipoNumero": "OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "status": "ENVIADA",
                  "enfileirada": false,
                  "custoEvitado": null,
                  "contatoOptout": false,
                  "janelaAberta": false,
                  "custoEstimado": {
                    "categoria": "MARKETING",
                    "centavos": 34,
                    "precoUsd": "0.0625",
                    "cambio": "5.4",
                    "tabelaVersao": 1,
                    "estimado": true
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/{id}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterMensagem",
        "tags": [
          "Mensagens"
        ],
        "summary": "Consulta uma mensagem",
        "description": "Status, tipo do número, tipo de envio, erro do canal (quando falhou) e, em número não oficial, o custo evitado. Depois da retenção de 90 dias o texto some (`removida: true`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da mensagem (`id` devolvido no envio ou no evento)."
            },
            "required": true,
            "description": "Identificador da mensagem (`id` devolvido no envio ou no evento).",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A mensagem.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mensagem"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      },
      "patch": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "editarMensagem",
        "tags": [
          "Mensagens"
        ],
        "summary": "Edita uma mensagem enviada (número não oficial)",
        "description": "Só mensagens de texto enviadas pelo número, até 15 minutos depois do envio (regra do WhatsApp; fora do prazo, 422). No oficial responde 422 `recurso_indisponivel`. Emite `mensagem.editada`. Não é mensagem nova: não passa pela cadência nem entra na economia. O canal é chamado primeiro; se ele recusar, responde 502 com o código do canal e nada muda. Com o aceite, a mensagem guardada muda e o evento correspondente sai com `autor: \"numero\"`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da mensagem."
            },
            "required": true,
            "description": "Identificador da mensagem.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "texto": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096
                  }
                },
                "required": [
                  "texto"
                ]
              },
              "example": {
                "texto": "Corrigindo: entrega no sábado."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A mensagem editada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mensagem"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      },
      "delete": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "apagarMensagem",
        "tags": [
          "Mensagens"
        ],
        "summary": "Apaga para todos (número não oficial)",
        "description": "Só mensagens enviadas pelo número, até 2 dias depois do envio. Texto e mídia são limpos. No oficial responde 422 `recurso_indisponivel`. Emite `mensagem.apagada`. Não é mensagem nova: não passa pela cadência nem entra na economia. O canal é chamado primeiro; se ele recusar, responde 502 com o código do canal e nada muda. Com o aceite, a mensagem guardada muda e o evento correspondente sai com `autor: \"numero\"`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da mensagem."
            },
            "required": true,
            "description": "Identificador da mensagem.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A mensagem apagada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mensagem"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/mensagens/{id}/reacao": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "reagirMensagem",
        "tags": [
          "Mensagens"
        ],
        "summary": "Reage a uma mensagem",
        "description": "Reação do número a qualquer mensagem da conversa (emoji vazio remove). Emite `mensagem.reacao`. Não é mensagem nova: não passa pela cadência nem entra na economia. O canal é chamado primeiro; se ele recusar, responde 502 com o código do canal e nada muda. Com o aceite, a mensagem guardada muda e o evento correspondente sai com `autor: \"numero\"`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da mensagem."
            },
            "required": true,
            "description": "Identificador da mensagem.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emoji": {
                    "type": "string",
                    "maxLength": 16,
                    "description": "Vazio remove a reação do número."
                  }
                },
                "required": [
                  "emoji"
                ]
              },
              "example": {
                "emoji": "✅"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A mensagem, com a reação.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mensagem"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/mensagens/{id}/votos": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "votosEnquete",
        "tags": [
          "Mensagens"
        ],
        "summary": "Resultado de uma enquete",
        "description": "Total de cada opção e o voto atual de cada contato. Só enquetes enviadas pelo número (outra mensagem → 422).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da enquete."
            },
            "required": true,
            "description": "Identificador da enquete.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Os votos.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mensagemId": {
                      "type": "string"
                    },
                    "pergunta": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "maxRespostas": {
                      "type": "integer"
                    },
                    "opcoes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "opcao": {
                            "type": "string"
                          },
                          "total": {
                            "type": "integer"
                          },
                          "telefones": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        },
                        "required": [
                          "opcao",
                          "total",
                          "telefones"
                        ]
                      },
                      "description": "Na ordem da enquete, com o total de votos atuais."
                    },
                    "votos": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "telefone": {
                            "type": "string"
                          },
                          "opcoes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "votadoEm": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "telefone",
                          "opcoes",
                          "votadoEm"
                        ]
                      },
                      "description": "Voto atual de cada contato (trocar o voto substitui o anterior)."
                    }
                  },
                  "required": [
                    "mensagemId",
                    "pergunta",
                    "maxRespostas",
                    "opcoes",
                    "votos"
                  ]
                },
                "example": {
                  "mensagemId": "clx0mensagem00000000000001",
                  "pergunta": "Qual o melhor dia para a entrega?",
                  "maxRespostas": 1,
                  "opcoes": [
                    {
                      "opcao": "Sexta-feira",
                      "total": 1,
                      "telefones": [
                        "5511987654321"
                      ]
                    },
                    {
                      "opcao": "Sábado",
                      "total": 0,
                      "telefones": []
                    }
                  ],
                  "votos": [
                    {
                      "telefone": "5511987654321",
                      "opcoes": [
                        "Sexta-feira"
                      ],
                      "votadoEm": "2026-10-14T13:07:00.000Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/mensagens/{id}/lida": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "marcarMensagemLida",
        "tags": [
          "Mensagens"
        ],
        "summary": "Marca uma mensagem recebida como lida",
        "description": "O contato vê os tiques azuis (se a privacidade dele permitir), e a conversa fica com `naoLidas = 0`. Só mensagens recebidas do contato.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da mensagem recebida."
            },
            "required": true,
            "description": "Identificador da mensagem recebida.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A mensagem.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mensagem"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/presenca": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "presencaConversa",
        "tags": [
          "Mensagens"
        ],
        "summary": "Mostra \"digitando…\" ao contato",
        "description": "Não oficial: `digitando`, `gravando` ou `parou`, visível por `duracaoMs`. Oficial: só `digitando`, que a Meta mostra por até 25 s ou até a resposta e que exige uma mensagem recebida do contato (sem ela, 422); `gravando` responde 422 e `parou` não faz nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "para": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
                  },
                  "estado": {
                    "type": "string",
                    "enum": [
                      "digitando",
                      "gravando",
                      "parou"
                    ]
                  },
                  "duracaoMs": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 25000,
                    "default": 5000,
                    "description": "Quanto tempo o indicador fica visível (não oficial). No oficial, a Meta mostra por até 25 s ou até a resposta."
                  }
                },
                "required": [
                  "numeroId",
                  "para",
                  "estado"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "para": "5511987654321",
                "estado": "digitando",
                "duracaoMs": 5000
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Indicador enviado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/contatos/verificar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "verificarContatos",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Verifica se telefones têm WhatsApp",
        "description": "Até 100 por chamada. Cada número verifica no máximo 1.000 telefones por hora (configurável pela plataforma); acima disso, 429 com `Retry-After` e nada vai ao WhatsApp, porque verificação em massa é sinal de automação. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Número NAO_OFICIAL conectado."
                  },
                  "telefones": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 8,
                      "maxLength": 30
                    },
                    "minItems": 1,
                    "maxItems": 100
                  }
                },
                "required": [
                  "numeroId",
                  "telefones"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "telefones": [
                  "5511987654321",
                  "27998765432"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado por telefone.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultados": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "telefone": {
                            "type": "string",
                            "description": "Como foi enviado."
                          },
                          "temWhatsapp": {
                            "type": "boolean"
                          },
                          "telefoneNormalizado": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Como o WhatsApp conhece o número (ex.: com ou sem o nono dígito)."
                          },
                          "contaComercial": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "telefone",
                          "temWhatsapp",
                          "telefoneNormalizado",
                          "contaComercial"
                        ]
                      }
                    },
                    "restanteNaHora": {
                      "type": "integer",
                      "description": "Quantos telefones este número ainda pode verificar na hora corrente."
                    }
                  },
                  "required": [
                    "resultados",
                    "restanteNaHora"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/contatos/{telefone}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterContato",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Recado, foto e conta comercial do contato",
        "description": "O que a privacidade do contato deixa ver; campo escondido vem nulo. `fotoUrl` é um link temporário do WhatsApp (`fotoExpiraEm`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Telefone do contato (E.164, com ou sem máscara)."
            },
            "required": true,
            "description": "Telefone do contato (E.164, com ou sem máscara).",
            "name": "telefone",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "Identificador público do número (`GET /v1/numeros`)."
            },
            "required": true,
            "description": "Identificador público do número (`GET /v1/numeros`).",
            "name": "numeroId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "O contato.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "telefone": {
                      "type": "string"
                    },
                    "temWhatsapp": {
                      "type": "boolean"
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Nome comercial verificado, quando houver."
                    },
                    "recado": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "fotoUrl": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Link temporário do WhatsApp; nulo se a privacidade do contato esconde a foto."
                    },
                    "fotoExpiraEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "contaComercial": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "telefone",
                    "temWhatsapp",
                    "nome",
                    "recado",
                    "fotoUrl",
                    "fotoExpiraEm",
                    "contaComercial"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/contatos/{telefone}/foto": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "fotoContato",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Baixa a foto do contato",
        "description": "Devolve a imagem (JPEG/PNG/WebP) com os mesmos cabeçalhos de segurança da mídia. 404 quando a privacidade esconde a foto. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Telefone do contato (E.164, com ou sem máscara)."
            },
            "required": true,
            "description": "Telefone do contato (E.164, com ou sem máscara).",
            "name": "telefone",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "Identificador público do número (`GET /v1/numeros`)."
            },
            "required": true,
            "description": "Identificador público do número (`GET /v1/numeros`).",
            "name": "numeroId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "A imagem.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/contatos/{telefone}/bloquear": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "bloquearContato",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Bloqueia o contato",
        "description": "Também registra opt-out do contato na conta (bloqueado não recebe mensagens). Auditado. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Telefone do contato (E.164, com ou sem máscara)."
            },
            "required": true,
            "description": "Telefone do contato (E.164, com ou sem máscara).",
            "name": "telefone",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  }
                },
                "required": [
                  "numeroId"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Bloqueado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/contatos/{telefone}/desbloquear": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "desbloquearContato",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Desbloqueia o contato",
        "description": "Não desfaz o opt-out (ele pode ter outra origem). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Telefone do contato (E.164, com ou sem máscara)."
            },
            "required": true,
            "description": "Telefone do contato (E.164, com ou sem máscara).",
            "name": "telefone",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  }
                },
                "required": [
                  "numeroId"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Desbloqueado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/bloqueados": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarBloqueados",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Contatos bloqueados pelo número",
        "description": "Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Telefones bloqueados.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "telefones": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "telefones"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/contatos": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "agendaNumero",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Agenda do número",
        "description": "Contatos que o WhatsApp do número conhece, lidos do celular sob demanda (cache de 5 minutos); o ZapHub não guarda a agenda. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "default": 0,
              "description": "Posição (o `proximoCursor` da página anterior)."
            },
            "required": false,
            "description": "Posição (o `proximoCursor` da página anterior).",
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "required": false,
            "name": "limite",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Uma página da agenda.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "itens": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "telefone": {
                            "type": "string"
                          },
                          "nome": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nome salvo na agenda do celular."
                          },
                          "nomePublico": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "nomeComercial": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "telefone",
                          "nome",
                          "nomePublico",
                          "nomeComercial"
                        ]
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "proximoCursor": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "itens",
                    "total",
                    "proximoCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/perfil": {
      "patch": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "perfilNumero",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Nome, recado e foto do número",
        "description": "Não oficial: nome, recado e foto (URL HTTPS pública ou base64 JPEG/PNG até 5 MB). Oficial: só o recado, que vai ao perfil comercial da Meta; `nome` responde 422 (é o nome verificado na Meta) e a foto é trocada no Gerenciador do WhatsApp. Auditado.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 25
                  },
                  "recado": {
                    "type": "string",
                    "maxLength": 139
                  },
                  "foto": {
                    "type": "string",
                    "maxLength": 7000000,
                    "description": "JPEG ou PNG em base64 (ou data URL), até 5 MB."
                  }
                }
              },
              "example": {
                "nome": "Loja Centro",
                "recado": "Atendemos das 8h às 18h"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Perfil alterado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/privacidade": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "privacidadeNumero",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Privacidade do número",
        "description": "Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Privacidade atual.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vistoPorUltimo": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "foto": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "recado": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "adicionarGrupos": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "confirmacaoLeitura": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "ninguem"
                      ]
                    }
                  },
                  "required": [
                    "vistoPorUltimo",
                    "foto",
                    "recado",
                    "adicionarGrupos",
                    "confirmacaoLeitura"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      },
      "put": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "definirPrivacidadeNumero",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Altera a privacidade do número",
        "description": "Só os campos enviados mudam. Auditado. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "vistoPorUltimo": {
                    "type": "string",
                    "enum": [
                      "todos",
                      "contatos",
                      "contatos_exceto",
                      "ninguem"
                    ]
                  },
                  "foto": {
                    "type": "string",
                    "enum": [
                      "todos",
                      "contatos",
                      "contatos_exceto",
                      "ninguem"
                    ]
                  },
                  "recado": {
                    "type": "string",
                    "enum": [
                      "todos",
                      "contatos",
                      "contatos_exceto",
                      "ninguem"
                    ]
                  },
                  "adicionarGrupos": {
                    "type": "string",
                    "enum": [
                      "todos",
                      "contatos",
                      "contatos_exceto",
                      "ninguem"
                    ]
                  },
                  "confirmacaoLeitura": {
                    "type": "string",
                    "enum": [
                      "todos",
                      "ninguem"
                    ]
                  }
                }
              },
              "example": {
                "vistoPorUltimo": "contatos"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Privacidade depois da alteração.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vistoPorUltimo": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "foto": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "recado": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "adicionarGrupos": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "contatos",
                        "contatos_exceto",
                        "ninguem"
                      ]
                    },
                    "confirmacaoLeitura": {
                      "type": "string",
                      "enum": [
                        "todos",
                        "ninguem"
                      ]
                    }
                  },
                  "required": [
                    "vistoPorUltimo",
                    "foto",
                    "recado",
                    "adicionarGrupos",
                    "confirmacaoLeitura"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/configuracoes": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "configuracoesNumero",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Configurações do número",
        "description": "Rejeitar chamadas, sempre online, ler automaticamente, ignorar grupos e status. Só NAO_OFICIAL (funciona com o número desconectado).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "As configurações.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rejeitarChamadas": {
                      "type": "boolean"
                    },
                    "mensagemRejeicao": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "maxLength": 500
                    },
                    "sempreOnline": {
                      "type": "boolean",
                      "description": "Aumenta o risco de banimento: comportamento não humano."
                    },
                    "lerAutomaticamente": {
                      "type": "boolean",
                      "description": "Aumenta o risco de banimento: comportamento não humano."
                    },
                    "ignorarGrupos": {
                      "type": "boolean"
                    },
                    "ignorarStatus": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "rejeitarChamadas",
                    "mensagemRejeicao",
                    "sempreOnline",
                    "lerAutomaticamente",
                    "ignorarGrupos",
                    "ignorarStatus"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      },
      "put": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "definirConfiguracoesNumero",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Altera as configurações do número",
        "description": "Aplicadas no Evolution primeiro; se ele recusar ou estiver fora, 502 e nada muda. Reaplicadas quando o número reconecta. `sempreOnline` e `lerAutomaticamente` são comportamento não humano e **aumentam o risco de banimento**. Com `rejeitarChamadas`, as chamadas são recusadas sem gerar `chamada.*`. Auditado.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rejeitarChamadas": {
                    "type": "boolean"
                  },
                  "mensagemRejeicao": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "sempreOnline": {
                    "type": "boolean",
                    "description": "Aumenta o risco de banimento: comportamento não humano."
                  },
                  "lerAutomaticamente": {
                    "type": "boolean",
                    "description": "Aumenta o risco de banimento: comportamento não humano."
                  },
                  "ignorarGrupos": {
                    "type": "boolean"
                  },
                  "ignorarStatus": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "rejeitarChamadas": true,
                "mensagemRejeicao": "Não atendemos ligações, mande mensagem"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "As configurações aplicadas.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rejeitarChamadas": {
                      "type": "boolean"
                    },
                    "mensagemRejeicao": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "maxLength": 500
                    },
                    "sempreOnline": {
                      "type": "boolean",
                      "description": "Aumenta o risco de banimento: comportamento não humano."
                    },
                    "lerAutomaticamente": {
                      "type": "boolean",
                      "description": "Aumenta o risco de banimento: comportamento não humano."
                    },
                    "ignorarGrupos": {
                      "type": "boolean"
                    },
                    "ignorarStatus": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "rejeitarChamadas",
                    "mensagemRejeicao",
                    "sempreOnline",
                    "lerAutomaticamente",
                    "ignorarGrupos",
                    "ignorarStatus"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/historico/sincronizar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "sincronizarHistorico",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Pede mais histórico de uma conversa ao celular",
        "description": "Parte da mensagem mais antiga que o ZapHub tem da conversa (sem nenhuma, 422). O resultado chega em `historico.sincronizado`. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "telefone": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 30,
                    "description": "Conversa a sincronizar."
                  },
                  "quantidade": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 50
                  }
                },
                "required": [
                  "telefone"
                ]
              },
              "example": {
                "telefone": "5511987654321",
                "quantidade": 50
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Pedido enviado ao celular.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/arquivar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "arquivarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Arquiva a conversa",
        "description": "Vale no WhatsApp do número; a conversa guarda o estado (`arquivada`, `fixada`, `silenciadaAte`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A conversa.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "tipoNumero": {
                      "type": "string",
                      "enum": [
                        "OFICIAL",
                        "NAO_OFICIAL"
                      ]
                    },
                    "contato": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "type": "string"
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "telefone",
                        "nome"
                      ]
                    },
                    "ultimaMensagemEm": {
                      "type": "string"
                    },
                    "ultimaEntradaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "janela24h": {
                      "type": "object",
                      "properties": {
                        "aberta": {
                          "type": "boolean"
                        },
                        "expiraEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "aberta",
                        "expiraEm"
                      ]
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "CONTATO",
                        "GRUPO"
                      ],
                      "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                    },
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      },
                      "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                    },
                    "arquivada": {
                      "type": "boolean"
                    },
                    "fixada": {
                      "type": "boolean"
                    },
                    "silenciadaAte": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Fim do silêncio; muito no futuro = sempre."
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "tipoNumero",
                    "contato",
                    "ultimaMensagemEm",
                    "ultimaEntradaEm",
                    "janela24h",
                    "tipo",
                    "etiquetas",
                    "arquivada",
                    "fixada",
                    "silenciadaAte"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/desarquivar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "desarquivarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Desarquiva a conversa",
        "description": "Vale no WhatsApp do número; a conversa guarda o estado (`arquivada`, `fixada`, `silenciadaAte`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A conversa.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "tipoNumero": {
                      "type": "string",
                      "enum": [
                        "OFICIAL",
                        "NAO_OFICIAL"
                      ]
                    },
                    "contato": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "type": "string"
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "telefone",
                        "nome"
                      ]
                    },
                    "ultimaMensagemEm": {
                      "type": "string"
                    },
                    "ultimaEntradaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "janela24h": {
                      "type": "object",
                      "properties": {
                        "aberta": {
                          "type": "boolean"
                        },
                        "expiraEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "aberta",
                        "expiraEm"
                      ]
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "CONTATO",
                        "GRUPO"
                      ],
                      "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                    },
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      },
                      "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                    },
                    "arquivada": {
                      "type": "boolean"
                    },
                    "fixada": {
                      "type": "boolean"
                    },
                    "silenciadaAte": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Fim do silêncio; muito no futuro = sempre."
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "tipoNumero",
                    "contato",
                    "ultimaMensagemEm",
                    "ultimaEntradaEm",
                    "janela24h",
                    "tipo",
                    "etiquetas",
                    "arquivada",
                    "fixada",
                    "silenciadaAte"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/fixar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "fixarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Fixa a conversa",
        "description": "Vale no WhatsApp do número; a conversa guarda o estado (`arquivada`, `fixada`, `silenciadaAte`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A conversa.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "tipoNumero": {
                      "type": "string",
                      "enum": [
                        "OFICIAL",
                        "NAO_OFICIAL"
                      ]
                    },
                    "contato": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "type": "string"
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "telefone",
                        "nome"
                      ]
                    },
                    "ultimaMensagemEm": {
                      "type": "string"
                    },
                    "ultimaEntradaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "janela24h": {
                      "type": "object",
                      "properties": {
                        "aberta": {
                          "type": "boolean"
                        },
                        "expiraEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "aberta",
                        "expiraEm"
                      ]
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "CONTATO",
                        "GRUPO"
                      ],
                      "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                    },
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      },
                      "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                    },
                    "arquivada": {
                      "type": "boolean"
                    },
                    "fixada": {
                      "type": "boolean"
                    },
                    "silenciadaAte": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Fim do silêncio; muito no futuro = sempre."
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "tipoNumero",
                    "contato",
                    "ultimaMensagemEm",
                    "ultimaEntradaEm",
                    "janela24h",
                    "tipo",
                    "etiquetas",
                    "arquivada",
                    "fixada",
                    "silenciadaAte"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/desafixar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "desafixarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Desafixa a conversa",
        "description": "Vale no WhatsApp do número; a conversa guarda o estado (`arquivada`, `fixada`, `silenciadaAte`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A conversa.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "tipoNumero": {
                      "type": "string",
                      "enum": [
                        "OFICIAL",
                        "NAO_OFICIAL"
                      ]
                    },
                    "contato": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "type": "string"
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "telefone",
                        "nome"
                      ]
                    },
                    "ultimaMensagemEm": {
                      "type": "string"
                    },
                    "ultimaEntradaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "janela24h": {
                      "type": "object",
                      "properties": {
                        "aberta": {
                          "type": "boolean"
                        },
                        "expiraEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "aberta",
                        "expiraEm"
                      ]
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "CONTATO",
                        "GRUPO"
                      ],
                      "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                    },
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      },
                      "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                    },
                    "arquivada": {
                      "type": "boolean"
                    },
                    "fixada": {
                      "type": "boolean"
                    },
                    "silenciadaAte": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Fim do silêncio; muito no futuro = sempre."
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "tipoNumero",
                    "contato",
                    "ultimaMensagemEm",
                    "ultimaEntradaEm",
                    "janela24h",
                    "tipo",
                    "etiquetas",
                    "arquivada",
                    "fixada",
                    "silenciadaAte"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/silenciar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "silenciarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Silencia a conversa",
        "description": "Vale no WhatsApp do número; a conversa guarda o estado (`arquivada`, `fixada`, `silenciadaAte`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "duracao": {
                    "type": "string",
                    "enum": [
                      "8h",
                      "1semana",
                      "sempre"
                    ]
                  }
                },
                "required": [
                  "duracao"
                ]
              },
              "example": {
                "duracao": "8h"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A conversa.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "tipoNumero": {
                      "type": "string",
                      "enum": [
                        "OFICIAL",
                        "NAO_OFICIAL"
                      ]
                    },
                    "contato": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "type": "string"
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "telefone",
                        "nome"
                      ]
                    },
                    "ultimaMensagemEm": {
                      "type": "string"
                    },
                    "ultimaEntradaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "janela24h": {
                      "type": "object",
                      "properties": {
                        "aberta": {
                          "type": "boolean"
                        },
                        "expiraEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "aberta",
                        "expiraEm"
                      ]
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "CONTATO",
                        "GRUPO"
                      ],
                      "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                    },
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      },
                      "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                    },
                    "arquivada": {
                      "type": "boolean"
                    },
                    "fixada": {
                      "type": "boolean"
                    },
                    "silenciadaAte": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Fim do silêncio; muito no futuro = sempre."
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "tipoNumero",
                    "contato",
                    "ultimaMensagemEm",
                    "ultimaEntradaEm",
                    "janela24h",
                    "tipo",
                    "etiquetas",
                    "arquivada",
                    "fixada",
                    "silenciadaAte"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/dessilenciar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "dessilenciarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Tira o silêncio da conversa",
        "description": "Vale no WhatsApp do número; a conversa guarda o estado (`arquivada`, `fixada`, `silenciadaAte`). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "A conversa.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "tipoNumero": {
                      "type": "string",
                      "enum": [
                        "OFICIAL",
                        "NAO_OFICIAL"
                      ]
                    },
                    "contato": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "type": "string"
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "telefone",
                        "nome"
                      ]
                    },
                    "ultimaMensagemEm": {
                      "type": "string"
                    },
                    "ultimaEntradaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "janela24h": {
                      "type": "object",
                      "properties": {
                        "aberta": {
                          "type": "boolean"
                        },
                        "expiraEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "aberta",
                        "expiraEm"
                      ]
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "CONTATO",
                        "GRUPO"
                      ],
                      "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                    },
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      },
                      "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                    },
                    "arquivada": {
                      "type": "boolean"
                    },
                    "fixada": {
                      "type": "boolean"
                    },
                    "silenciadaAte": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Fim do silêncio; muito no futuro = sempre."
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "tipoNumero",
                    "contato",
                    "ultimaMensagemEm",
                    "ultimaEntradaEm",
                    "janela24h",
                    "tipo",
                    "etiquetas",
                    "arquivada",
                    "fixada",
                    "silenciadaAte"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/chamadas/{chamadaId}/rejeitar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "rejeitarChamada",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Rejeita uma chamada recebida",
        "description": "Use o `chamadaId` de `chamada.recebida`. Chamada já encerrada → 409. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`; desconectado → 409). Falha do WhatsApp → 502, sem alterar nada.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "`chamadaId` do evento `chamada.recebida`."
            },
            "required": true,
            "description": "`chamadaId` do evento `chamada.recebida`.",
            "name": "chamadaId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  }
                },
                "required": [
                  "numeroId"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Chamada rejeitada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/status": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "publicarStatus",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Publica no status (stories) do número",
        "description": "Só NAO_OFICIAL. Texto puro (o Evolution Go não aplica cor de fundo nem fonte) ou imagem/vídeo por URL HTTPS pública ou base64 (via armazenamento). Aparece para os contatos, conforme a privacidade de status do número. Limite de 30 por número em 24h (configurável na plataforma); acima, 429 com `Retry-After`. Não entra na caixa de entrada nem na economia.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tipo": {
                    "type": "string",
                    "enum": [
                      "texto",
                      "midia"
                    ]
                  },
                  "texto": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 700,
                    "description": "Só em `texto`. O Evolution Go publica o texto sem cor de fundo nem fonte."
                  },
                  "midia": {
                    "type": "object",
                    "properties": {
                      "tipo": {
                        "type": "string",
                        "enum": [
                          "imagem",
                          "video"
                        ]
                      },
                      "url": {
                        "type": "string",
                        "maxLength": 2048,
                        "description": "URL HTTPS pública."
                      },
                      "base64": {
                        "type": "string",
                        "maxLength": 23000000
                      },
                      "mimeType": {
                        "type": "string",
                        "maxLength": 100
                      }
                    },
                    "required": [
                      "tipo"
                    ],
                    "description": "Só em `midia`: `url` ou `base64` (com `mimeType`)."
                  },
                  "legenda": {
                    "type": "string",
                    "maxLength": 700
                  }
                },
                "required": [
                  "tipo"
                ]
              },
              "example": {
                "tipo": "midia",
                "midia": {
                  "tipo": "imagem",
                  "url": "https://cdn.exemplo.com.br/promo.jpg"
                },
                "legenda": "Só hoje: frete grátis"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Publicado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "restanteHoje": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "restanteHoje"
                  ]
                },
                "example": {
                  "restanteHoje": 29
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/comunidades": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "criarComunidade",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Cria uma comunidade",
        "description": "Conta no limite diário de grupos criados por número (429 com `Retry-After`). Auditado. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "numeroId",
                  "nome"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "nome": "Moradores do bairro"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A comunidade criada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "JID da comunidade no WhatsApp (`...@g.us`)."
                    },
                    "nome": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "nome"
                  ]
                },
                "example": {
                  "id": "120363000000000009@g.us",
                  "nome": "Moradores do bairro"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/comunidades/{comunidadeId}/grupos": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "gruposComunidade",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Adiciona ou remove grupos da comunidade",
        "description": "`grupoIds` são os `id` de `GET /v1/numeros/{id}/grupos`; o número precisa ser admin dos grupos. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "`id` da comunidade (termina em `@g.us`)."
            },
            "required": true,
            "description": "`id` da comunidade (termina em `@g.us`).",
            "name": "comunidadeId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "acao": {
                    "type": "string",
                    "enum": [
                      "adicionar",
                      "remover"
                    ]
                  },
                  "grupoIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "`id` dos grupos (de `GET /v1/numeros/{id}/grupos`)."
                  }
                },
                "required": [
                  "numeroId",
                  "acao",
                  "grupoIds"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "acao": "adicionar",
                "grupoIds": [
                  "clx0grupo000000000000001"
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Feito.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/canais": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarCanais",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Canais que o número segue ou administra",
        "description": "Consulta o WhatsApp a cada chamada. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Os canais.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "canais": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "JID do canal (`...@newsletter`)."
                          },
                          "nome": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "descricao": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "seguidores": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "convite": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Link de convite do canal."
                          },
                          "papel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Papel do número no canal (`owner`, `admin`, `subscriber`…)."
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "descricao",
                          "seguidores",
                          "convite",
                          "papel"
                        ]
                      }
                    }
                  },
                  "required": [
                    "canais"
                  ]
                },
                "example": {
                  "canais": [
                    {
                      "id": "120363100000000001@newsletter",
                      "nome": "Ofertas da Loja",
                      "descricao": "Novidades toda semana",
                      "seguidores": 42,
                      "convite": "https://whatsapp.com/channel/0029VaExemplo123456",
                      "papel": "owner"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      },
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "criarCanal",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Cria um canal",
        "description": "Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "descricao": {
                    "type": "string",
                    "maxLength": 2048
                  }
                },
                "required": [
                  "nome"
                ]
              },
              "example": {
                "nome": "Ofertas da Loja",
                "descricao": "Novidades toda semana"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "O canal criado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "JID do canal (`...@newsletter`)."
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descricao": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "seguidores": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "convite": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Link de convite do canal."
                    },
                    "papel": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Papel do número no canal (`owner`, `admin`, `subscriber`…)."
                    }
                  },
                  "required": [
                    "id",
                    "nome",
                    "descricao",
                    "seguidores",
                    "convite",
                    "papel"
                  ]
                },
                "example": {
                  "id": "120363100000000001@newsletter",
                  "nome": "Ofertas da Loja",
                  "descricao": "Novidades toda semana",
                  "seguidores": 42,
                  "convite": "https://whatsapp.com/channel/0029VaExemplo123456",
                  "papel": "owner"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/canais/convite": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "canalPorConvite",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Abre um link de convite de canal",
        "description": "Devolve os dados do canal sem segui-lo. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "link": {
                    "type": "string",
                    "pattern": "^(https:\\/\\/whatsapp\\.com\\/channel\\/)?[A-Za-z0-9]{10,40}$"
                  }
                },
                "required": [
                  "numeroId",
                  "link"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "link": "https://whatsapp.com/channel/0029VaExemplo123456"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "O canal.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "JID do canal (`...@newsletter`)."
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descricao": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "seguidores": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "convite": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Link de convite do canal."
                    },
                    "papel": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Papel do número no canal (`owner`, `admin`, `subscriber`…)."
                    }
                  },
                  "required": [
                    "id",
                    "nome",
                    "descricao",
                    "seguidores",
                    "convite",
                    "papel"
                  ]
                },
                "example": {
                  "id": "120363100000000001@newsletter",
                  "nome": "Ofertas da Loja",
                  "descricao": "Novidades toda semana",
                  "seguidores": 42,
                  "convite": "https://whatsapp.com/channel/0029VaExemplo123456",
                  "papel": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/canais/{canalId}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterCanal",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Detalhes de um canal",
        "description": "Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "`id` do canal (termina em `@newsletter`)."
            },
            "required": true,
            "description": "`id` do canal (termina em `@newsletter`).",
            "name": "canalId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "Identificador público do número (`GET /v1/numeros`)."
            },
            "required": true,
            "description": "Identificador público do número (`GET /v1/numeros`).",
            "name": "numeroId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "O canal.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "JID do canal (`...@newsletter`)."
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descricao": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "seguidores": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "convite": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Link de convite do canal."
                    },
                    "papel": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Papel do número no canal (`owner`, `admin`, `subscriber`…)."
                    }
                  },
                  "required": [
                    "id",
                    "nome",
                    "descricao",
                    "seguidores",
                    "convite",
                    "papel"
                  ]
                },
                "example": {
                  "id": "120363100000000001@newsletter",
                  "nome": "Ofertas da Loja",
                  "descricao": "Novidades toda semana",
                  "seguidores": 42,
                  "convite": "https://whatsapp.com/channel/0029VaExemplo123456",
                  "papel": "owner"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/canais/{canalId}/mensagens": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "mensagensCanal",
        "tags": [
          "Comunidades e canais"
        ],
        "summary": "Publicações do canal",
        "description": "Da mais nova para a mais antiga; para a página seguinte, passe o `antesDe` da resposta. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "`id` do canal (termina em `@newsletter`)."
            },
            "required": true,
            "description": "`id` do canal (termina em `@newsletter`).",
            "name": "canalId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "Identificador público do número (`GET /v1/numeros`)."
            },
            "required": true,
            "description": "Identificador público do número (`GET /v1/numeros`).",
            "name": "numeroId",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "required": false,
            "name": "quantidade",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "`servidorId` da mensagem mais antiga da página anterior."
            },
            "required": false,
            "description": "`servidorId` da mensagem mais antiga da página anterior.",
            "name": "antesDe",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "As publicações.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mensagens": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "servidorId": {
                            "type": "integer"
                          },
                          "tipo": {
                            "type": "string"
                          },
                          "texto": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "enviadaEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "visualizacoes": {
                            "type": "integer"
                          },
                          "reacoes": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "integer"
                            }
                          }
                        },
                        "required": [
                          "id",
                          "servidorId",
                          "tipo",
                          "texto",
                          "enviadaEm",
                          "visualizacoes",
                          "reacoes"
                        ]
                      }
                    },
                    "antesDe": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Passe em `antesDe` para a página seguinte (mais antiga)."
                    }
                  },
                  "required": [
                    "mensagens",
                    "antesDe"
                  ]
                },
                "example": {
                  "mensagens": [
                    {
                      "id": "3EB0A1B2C3D4",
                      "servidorId": 120,
                      "tipo": "text",
                      "texto": "Promoção relâmpago hoje!",
                      "enviadaEm": "2026-11-01T12:00:00.000Z",
                      "visualizacoes": 310,
                      "reacoes": {
                        "👍": 12
                      }
                    }
                  ],
                  "antesDe": 120
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/etiquetas": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarEtiquetas",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Etiquetas do número",
        "description": "Sincroniza com o WhatsApp e lista. Só números `NAO_OFICIAL` com WhatsApp Business (sem Business → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "As etiquetas.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "etiquetas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "cor": {
                            "type": "integer",
                            "description": "Índice da cor do WhatsApp (0 a 19)."
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "cor"
                        ]
                      }
                    }
                  },
                  "required": [
                    "etiquetas"
                  ]
                },
                "example": {
                  "etiquetas": [
                    {
                      "id": "clx0etiqueta0000000000001",
                      "nome": "Pagamento pendente",
                      "cor": 3
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      },
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "salvarEtiqueta",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Cria ou edita uma etiqueta",
        "description": "Sem `etiquetaId`, cria. Emite `etiqueta.alterada` quando o WhatsApp confirma. Só números `NAO_OFICIAL` com WhatsApp Business (sem Business → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "etiquetaId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Para editar uma existente; sem ele, cria."
                  },
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "cor": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 19,
                    "default": 0
                  }
                },
                "required": [
                  "nome"
                ]
              },
              "example": {
                "nome": "Pagamento pendente",
                "cor": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A etiqueta.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "nome": {
                      "type": "string"
                    },
                    "cor": {
                      "type": "integer",
                      "description": "Índice da cor do WhatsApp (0 a 19)."
                    }
                  },
                  "required": [
                    "id",
                    "nome",
                    "cor"
                  ]
                },
                "example": {
                  "id": "clx0etiqueta0000000000001",
                  "nome": "Pagamento pendente",
                  "cor": 3
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/etiquetas/{etiquetaId}": {
      "delete": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "removerEtiqueta",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Remove uma etiqueta",
        "description": "Também some das conversas. Só números `NAO_OFICIAL` com WhatsApp Business (sem Business → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Identificador da etiqueta."
            },
            "required": true,
            "description": "Identificador da etiqueta.",
            "name": "etiquetaId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "204": {
            "description": "Removida.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas/{id}/etiquetas": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "etiquetarConversa",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Aplica ou tira uma etiqueta da conversa",
        "description": "As etiquetas da conversa aparecem em `GET /v1/conversas` (`conversa.etiquetas`). Só números `NAO_OFICIAL` com WhatsApp Business (sem Business → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da conversa."
            },
            "required": true,
            "description": "Identificador da conversa.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "etiquetaId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "acao": {
                    "type": "string",
                    "enum": [
                      "aplicar",
                      "remover"
                    ]
                  }
                },
                "required": [
                  "etiquetaId",
                  "acao"
                ]
              },
              "example": {
                "etiquetaId": "clx0etiqueta0000000000001",
                "acao": "aplicar"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Feito.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/mensagens/{id}/etiquetas": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "etiquetarMensagem",
        "tags": [
          "Contatos e configurações"
        ],
        "summary": "Aplica ou tira uma etiqueta da mensagem",
        "description": "Só números `NAO_OFICIAL` com WhatsApp Business (sem Business → 422 `recurso_indisponivel`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da mensagem."
            },
            "required": true,
            "description": "Identificador da mensagem.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "etiquetaId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "acao": {
                    "type": "string",
                    "enum": [
                      "aplicar",
                      "remover"
                    ]
                  }
                },
                "required": [
                  "etiquetaId",
                  "acao"
                ]
              },
              "example": {
                "etiquetaId": "clx0etiqueta0000000000001",
                "acao": "aplicar"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Feito.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/numeros/{id}/grupos": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarGrupos",
        "tags": [
          "Grupos"
        ],
        "summary": "Grupos do número",
        "description": "Lidos do WhatsApp na hora; o ZapHub guarda nome, configurações e se o número é admin. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do número."
            },
            "required": true,
            "description": "Identificador do número.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Os grupos.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "grupos": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "numeroId": {
                            "type": "string"
                          },
                          "nome": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "descricao": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "soAdminsEnviam": {
                            "type": "boolean"
                          },
                          "soAdminsEditam": {
                            "type": "boolean"
                          },
                          "numeroEhAdmin": {
                            "type": "boolean"
                          },
                          "participantes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "telefone": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Nulo quando o WhatsApp só informa o identificador privado."
                                },
                                "admin": {
                                  "type": "boolean"
                                },
                                "superAdmin": {
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "telefone",
                                "admin",
                                "superAdmin"
                              ]
                            },
                            "description": "Só em `GET /v1/grupos/{id}` (lido do WhatsApp, cache de 1 minuto)."
                          },
                          "totalParticipantes": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "numeroId",
                          "nome",
                          "descricao",
                          "soAdminsEnviam",
                          "soAdminsEditam",
                          "numeroEhAdmin"
                        ]
                      }
                    }
                  },
                  "required": [
                    "grupos"
                  ]
                },
                "example": {
                  "grupos": [
                    {
                      "id": "clx0grupo00000000000000001",
                      "numeroId": "clx0numero000000000000001",
                      "nome": "Clientes VIP",
                      "descricao": "Ofertas da semana",
                      "soAdminsEnviam": false,
                      "soAdminsEditam": true,
                      "numeroEhAdmin": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "criarGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Cria um grupo",
        "description": "Até 50 participantes por chamada. Limites por número em 24h (padrão: 10 grupos e 200 participantes adicionados); acima, 429 com `Retry-After`. Criar grupos e adicionar pessoas em massa é sinal de spam para o WhatsApp. Auditado. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Número NAO_OFICIAL conectado."
                  },
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "participantes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 8,
                      "maxLength": 30
                    },
                    "minItems": 1,
                    "maxItems": 50
                  }
                },
                "required": [
                  "numeroId",
                  "nome",
                  "participantes"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "nome": "Clientes VIP",
                "participantes": [
                  "5511987654321"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "O grupo criado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descricao": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "soAdminsEnviam": {
                      "type": "boolean"
                    },
                    "soAdminsEditam": {
                      "type": "boolean"
                    },
                    "numeroEhAdmin": {
                      "type": "boolean"
                    },
                    "participantes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "telefone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nulo quando o WhatsApp só informa o identificador privado."
                          },
                          "admin": {
                            "type": "boolean"
                          },
                          "superAdmin": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "telefone",
                          "admin",
                          "superAdmin"
                        ]
                      },
                      "description": "Só em `GET /v1/grupos/{id}` (lido do WhatsApp, cache de 1 minuto)."
                    },
                    "totalParticipantes": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "nome",
                    "descricao",
                    "soAdminsEnviam",
                    "soAdminsEditam",
                    "numeroEhAdmin"
                  ]
                },
                "example": {
                  "id": "clx0grupo00000000000000001",
                  "numeroId": "clx0numero000000000000001",
                  "nome": "Clientes VIP",
                  "descricao": "Ofertas da semana",
                  "soAdminsEnviam": false,
                  "soAdminsEditam": true,
                  "numeroEhAdmin": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos/entrar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "entrarGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Entra num grupo por link de convite",
        "description": "O grupo aparece em `grupo.entrou` e na próxima listagem. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Identificador público do número (`GET /v1/numeros`)."
                  },
                  "link": {
                    "type": "string",
                    "pattern": "^(https:\\/\\/chat\\.whatsapp\\.com\\/)?[A-Za-z0-9]{10,40}$"
                  }
                },
                "required": [
                  "numeroId",
                  "link"
                ]
              },
              "example": {
                "numeroId": "clx0numero000000000000001",
                "link": "https://chat.whatsapp.com/AbCdEfGhIjKlMnOpQrStUv"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Pedido enviado ao WhatsApp.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos/{id}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Detalhe do grupo com participantes",
        "description": "Participantes lidos do WhatsApp (cache de 1 minuto). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`)."
            },
            "required": true,
            "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`).",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O grupo.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descricao": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "soAdminsEnviam": {
                      "type": "boolean"
                    },
                    "soAdminsEditam": {
                      "type": "boolean"
                    },
                    "numeroEhAdmin": {
                      "type": "boolean"
                    },
                    "participantes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "telefone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nulo quando o WhatsApp só informa o identificador privado."
                          },
                          "admin": {
                            "type": "boolean"
                          },
                          "superAdmin": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "telefone",
                          "admin",
                          "superAdmin"
                        ]
                      },
                      "description": "Só em `GET /v1/grupos/{id}` (lido do WhatsApp, cache de 1 minuto)."
                    },
                    "totalParticipantes": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "nome",
                    "descricao",
                    "soAdminsEnviam",
                    "soAdminsEditam",
                    "numeroEhAdmin"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      },
      "patch": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "editarGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Edita nome, descrição, foto e configurações",
        "description": "Com \"só admins editam\", nome, descrição e foto exigem que o número seja admin; as configurações sempre exigem (422). Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`)."
            },
            "required": true,
            "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`).",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "descricao": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "foto": {
                    "type": "string",
                    "maxLength": 7000000,
                    "description": "JPEG ou PNG: URL HTTPS pública ou base64."
                  },
                  "soAdminsEnviam": {
                    "type": "boolean"
                  },
                  "soAdminsEditam": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "descricao": "Ofertas da semana",
                "soAdminsEnviam": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "O grupo.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "numeroId": {
                      "type": "string"
                    },
                    "nome": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descricao": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "soAdminsEnviam": {
                      "type": "boolean"
                    },
                    "soAdminsEditam": {
                      "type": "boolean"
                    },
                    "numeroEhAdmin": {
                      "type": "boolean"
                    },
                    "participantes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "telefone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nulo quando o WhatsApp só informa o identificador privado."
                          },
                          "admin": {
                            "type": "boolean"
                          },
                          "superAdmin": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "telefone",
                          "admin",
                          "superAdmin"
                        ]
                      },
                      "description": "Só em `GET /v1/grupos/{id}` (lido do WhatsApp, cache de 1 minuto)."
                    },
                    "totalParticipantes": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "numeroId",
                    "nome",
                    "descricao",
                    "soAdminsEnviam",
                    "soAdminsEditam",
                    "numeroEhAdmin"
                  ]
                },
                "example": {
                  "id": "clx0grupo00000000000000001",
                  "numeroId": "clx0numero000000000000001",
                  "nome": "Clientes VIP",
                  "descricao": "Ofertas da semana",
                  "soAdminsEnviam": false,
                  "soAdminsEditam": true,
                  "numeroEhAdmin": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos/{id}/participantes": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "participantesGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Adiciona, remove, promove ou rebaixa participantes",
        "description": "Só se o número for admin (422). Adicionar conta no limite diário de participantes (429). Auditado. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`)."
            },
            "required": true,
            "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`).",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "acao": {
                    "type": "string",
                    "enum": [
                      "adicionar",
                      "remover",
                      "promover",
                      "rebaixar"
                    ]
                  },
                  "telefones": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 8,
                      "maxLength": 30
                    },
                    "minItems": 1,
                    "maxItems": 50
                  }
                },
                "required": [
                  "acao",
                  "telefones"
                ]
              },
              "example": {
                "acao": "adicionar",
                "telefones": [
                  "5511987654321"
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Feito.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos/{id}/convite": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "conviteGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Link de convite do grupo",
        "description": "Só admins. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`)."
            },
            "required": true,
            "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`).",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O link.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "link": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "link"
                  ]
                },
                "example": {
                  "link": "https://chat.whatsapp.com/AbCdEfGhIjKlMnOpQrStUv"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos/{id}/convite/revogar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "revogarConviteGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "Revoga o link de convite e gera outro",
        "description": "Só admins. Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`)."
            },
            "required": true,
            "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`).",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "O link novo.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "link": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "link"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/grupos/{id}/participacao": {
      "delete": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "sairGrupo",
        "tags": [
          "Grupos"
        ],
        "summary": "O número sai do grupo",
        "description": "Só números `NAO_OFICIAL` conectados (oficial → 422 `recurso_indisponivel`). Falha do WhatsApp → 502.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`)."
            },
            "required": true,
            "description": "Identificador do grupo (`id` de `GET /v1/numeros/{id}/grupos`).",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "responses": {
          "204": {
            "description": "Saiu.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "502": {
            "$ref": "#/components/responses/Erro502"
          }
        }
      }
    },
    "/v1/conversas": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterConversa",
        "tags": [
          "Mensagens"
        ],
        "summary": "Histórico de uma conversa",
        "description": "Mensagens de um contato em um número, da mais nova para a mais antiga, paginadas por cursor (`proximoCursor` → `cursor`). Respeita a retenção de 90 dias.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "Identificador público do número (`GET /v1/numeros`)."
            },
            "required": true,
            "description": "Identificador público do número (`GET /v1/numeros`).",
            "name": "numeroId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 30,
              "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`."
            },
            "required": true,
            "description": "Telefone do contato com DDI e DDD. Aceita máscara (`+55 (11) 98765-4321`); sem DDI e com 10 ou 11 dígitos assume o Brasil (55). Normalizado para E.164 sem `+`.",
            "name": "telefone",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "`proximoCursor` da página anterior (mensagens mais antigas)."
            },
            "required": false,
            "description": "`proximoCursor` da página anterior (mensagens mais antigas).",
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 40
            },
            "required": false,
            "name": "limite",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "A conversa e a página de mensagens.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversa": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "numeroId": {
                          "type": "string"
                        },
                        "tipoNumero": {
                          "type": "string",
                          "enum": [
                            "OFICIAL",
                            "NAO_OFICIAL"
                          ]
                        },
                        "contato": {
                          "type": "object",
                          "properties": {
                            "telefone": {
                              "type": "string"
                            },
                            "nome": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "telefone",
                            "nome"
                          ]
                        },
                        "ultimaMensagemEm": {
                          "type": "string"
                        },
                        "ultimaEntradaEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "janela24h": {
                          "type": "object",
                          "properties": {
                            "aberta": {
                              "type": "boolean"
                            },
                            "expiraEm": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "aberta",
                            "expiraEm"
                          ]
                        },
                        "tipo": {
                          "type": "string",
                          "enum": [
                            "CONTATO",
                            "GRUPO"
                          ],
                          "description": "Em GRUPO, `contato.telefone` é o JID do grupo e `contato.nome` o nome dele."
                        },
                        "etiquetas": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "nome": {
                                "type": "string"
                              },
                              "cor": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "id",
                              "nome",
                              "cor"
                            ]
                          },
                          "description": "Etiquetas do WhatsApp Business aplicadas (não oficial)."
                        },
                        "arquivada": {
                          "type": "boolean"
                        },
                        "fixada": {
                          "type": "boolean"
                        },
                        "silenciadaAte": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Fim do silêncio; muito no futuro = sempre."
                        }
                      },
                      "required": [
                        "id",
                        "numeroId",
                        "tipoNumero",
                        "contato",
                        "ultimaMensagemEm",
                        "ultimaEntradaEm",
                        "janela24h",
                        "tipo",
                        "etiquetas",
                        "arquivada",
                        "fixada",
                        "silenciadaAte"
                      ]
                    },
                    "mensagens": {
                      "type": "object",
                      "properties": {
                        "itens": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "numeroId": {
                                "type": "string"
                              },
                              "tipoNumero": {
                                "type": "string",
                                "enum": [
                                  "OFICIAL",
                                  "NAO_OFICIAL"
                                ]
                              },
                              "conversaId": {
                                "type": "string"
                              },
                              "contato": {
                                "type": "object",
                                "properties": {
                                  "telefone": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "telefone"
                                ]
                              },
                              "direcao": {
                                "type": "string",
                                "enum": [
                                  "ENTRADA",
                                  "SAIDA"
                                ]
                              },
                              "origem": {
                                "type": "string",
                                "enum": [
                                  "CONTATO",
                                  "CELULAR",
                                  "PAINEL",
                                  "API",
                                  "AUTO",
                                  "CAMPANHA",
                                  "REPASSE"
                                ]
                              },
                              "tipoEnvio": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "enum": [
                                  "PRIMEIRO_CONTATO",
                                  "PRIMEIRA_RESPOSTA",
                                  "CONVERSA",
                                  "RETOMADA",
                                  "CONTATO_LEAD",
                                  "AUTO_RESPOSTA",
                                  "CAMPANHA",
                                  "GRUPO"
                                ]
                              },
                              "tipoConteudo": {
                                "type": "string",
                                "enum": [
                                  "TEXTO",
                                  "IMAGEM",
                                  "AUDIO",
                                  "VIDEO",
                                  "DOCUMENTO",
                                  "LOCALIZACAO",
                                  "TEMPLATE",
                                  "CONTATO",
                                  "FIGURINHA",
                                  "ENQUETE",
                                  "OUTRO"
                                ]
                              },
                              "texto": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Nulo depois da retenção (`removida`)."
                              },
                              "midia": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "tipo": {
                                    "type": "string",
                                    "enum": [
                                      "IMAGEM",
                                      "AUDIO",
                                      "VIDEO",
                                      "DOCUMENTO"
                                    ]
                                  },
                                  "mimeType": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "disponivel": {
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "tipo",
                                  "mimeType",
                                  "disponivel"
                                ]
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "ENFILEIRADA",
                                  "ENVIADA",
                                  "ENTREGUE",
                                  "LIDA",
                                  "FALHOU",
                                  "RECEBIDA"
                                ]
                              },
                              "enfileirada": {
                                "type": "boolean"
                              },
                              "contatoOptout": {
                                "type": "boolean"
                              },
                              "custoEvitado": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "marketingCentavos": {
                                    "type": "integer"
                                  },
                                  "utilityCentavos": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "marketingCentavos",
                                  "utilityCentavos"
                                ]
                              },
                              "erro": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "codigo": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "mensagem": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "codigo",
                                  "mensagem"
                                ]
                              },
                              "criadoEm": {
                                "type": "string"
                              },
                              "enviadoEm": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "entregueEm": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "lidoEm": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "removida": {
                                "type": "boolean",
                                "description": "Conteúdo removido pela retenção de 90 dias; os metadados permanecem."
                              },
                              "editadaEm": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "O autor editou a mensagem (o texto já é o novo)."
                              },
                              "apagadaEm": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "O autor apagou para todos: texto e mídia foram limpos."
                              },
                              "reacoes": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "autor": {
                                      "type": "string",
                                      "enum": [
                                        "contato",
                                        "numero"
                                      ]
                                    },
                                    "emoji": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "autor",
                                    "emoji"
                                  ]
                                },
                                "description": "Reação atual de cada lado."
                              },
                              "contatos": {
                                "type": [
                                  "array",
                                  "null"
                                ],
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "nome": {
                                      "type": "string"
                                    },
                                    "telefones": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "empresa": {
                                      "type": "string"
                                    },
                                    "email": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "nome",
                                    "telefones"
                                  ]
                                },
                                "description": "Só em `tipoConteudo: CONTATO`."
                              },
                              "enquete": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "maxRespostas": {
                                    "type": "integer"
                                  },
                                  "opcoes": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "opcao": {
                                          "type": "string"
                                        },
                                        "total": {
                                          "type": "integer"
                                        }
                                      },
                                      "required": [
                                        "opcao",
                                        "total"
                                      ]
                                    }
                                  }
                                },
                                "required": [
                                  "maxRespostas",
                                  "opcoes"
                                ],
                                "description": "Só em enquetes enviadas pelo número; o detalhe por contato está em `GET /v1/mensagens/{id}/votos`."
                              },
                              "respondendoA": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "trecho": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "id",
                                  "trecho"
                                ],
                                "description": "Mensagem citada."
                              },
                              "remetente": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "telefone": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "nome": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "telefone",
                                  "nome"
                                ],
                                "description": "Só em grupo: quem escreveu."
                              },
                              "interativo": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "tipo": {
                                    "type": "string",
                                    "enum": [
                                      "botoes",
                                      "lista",
                                      "link"
                                    ]
                                  },
                                  "opcoes": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  }
                                },
                                "required": [
                                  "tipo",
                                  "opcoes"
                                ],
                                "description": "Mensagem interativa enviada (oficial): o tipo e os títulos das opções."
                              },
                              "interacao": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "properties": {
                                  "tipo": {
                                    "type": "string",
                                    "enum": [
                                      "botao",
                                      "lista"
                                    ]
                                  },
                                  "id": {
                                    "type": "string"
                                  },
                                  "titulo": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "tipo",
                                  "id",
                                  "titulo"
                                ],
                                "description": "Resposta do contato a uma interativa: o botão ou item escolhido."
                              }
                            },
                            "required": [
                              "id",
                              "numeroId",
                              "tipoNumero",
                              "conversaId",
                              "contato",
                              "direcao",
                              "origem",
                              "tipoEnvio",
                              "tipoConteudo",
                              "texto",
                              "midia",
                              "status",
                              "enfileirada",
                              "contatoOptout",
                              "custoEvitado",
                              "erro",
                              "criadoEm",
                              "enviadoEm",
                              "entregueEm",
                              "lidoEm",
                              "removida",
                              "editadaEm",
                              "apagadaEm",
                              "reacoes",
                              "contatos",
                              "enquete",
                              "respondendoA",
                              "remetente",
                              "interativo",
                              "interacao"
                            ]
                          },
                          "description": "Da mais nova para a mais antiga."
                        },
                        "proximoCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "itens",
                        "proximoCursor"
                      ]
                    }
                  },
                  "required": [
                    "conversa",
                    "mensagens"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/campanhas": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "criarCampanha",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Cria uma campanha (número oficial)",
        "description": "Somente números `OFICIAL` (em `NAO_OFICIAL`: 422 `campanha_exige_api_oficial`). Informe os contatos **inline** (até 50.000, cada um com suas `variaveis`) **ou** uma `listaId`. Responde **202** com o id e a estimativa de custo; a campanha já sai disparando (use `agendadaPara` para agendar ou `iniciar: false` para criar como rascunho). Cada mudança de estado emite `campanha.status`.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "numeroId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Número OFICIAL."
                  },
                  "templateId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "`id` do template em `GET /v1/numeros/{id}/templates`."
                  },
                  "listaId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "description": "Lista de contatos já criada no painel. Use `listaId` OU `contatos`."
                  },
                  "contatos": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "telefone": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "number"
                            }
                          ],
                          "description": "Telefone com DDD (e DDI se não for do Brasil, com `+`)."
                        },
                        "nome": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "maxLength": 200
                        },
                        "variaveis": {
                          "type": "array",
                          "items": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "maxItems": 20,
                          "description": "Valores das variáveis do template para este contato, na ordem (`{{1}}`, `{{2}}`…). Dispensa o `mapeamento`."
                        },
                        "campos": {
                          "type": "object",
                          "additionalProperties": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              }
                            ]
                          },
                          "description": "Campos extras, referenciáveis no `mapeamento`."
                        }
                      },
                      "required": [
                        "telefone"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 50000,
                    "description": "Contatos inline (até 50.000), cada um com suas variáveis."
                  },
                  "mapeamento": {
                    "type": "object",
                    "additionalProperties": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "tipo": {
                              "type": "string",
                              "enum": [
                                "campo"
                              ]
                            },
                            "valor": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 100
                            }
                          },
                          "required": [
                            "tipo",
                            "valor"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "tipo": {
                              "type": "string",
                              "enum": [
                                "fixo"
                              ]
                            },
                            "valor": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 1000
                            }
                          },
                          "required": [
                            "tipo",
                            "valor"
                          ]
                        }
                      ]
                    },
                    "description": "Posição da variável (`\"1\"`) → campo do contato ou valor fixo. Omita quando os contatos trazem `variaveis`."
                  },
                  "agendadaPara": {
                    "type": "string",
                    "description": "Sem fuso explícito vale o horário de Brasília."
                  },
                  "pausaAutomatica": {
                    "type": "boolean",
                    "default": false
                  },
                  "iniciar": {
                    "type": "boolean",
                    "default": true,
                    "description": "true (padrão) dispara agora; ignorado se houver `agendadaPara`. false cria como rascunho."
                  }
                },
                "required": [
                  "nome",
                  "numeroId",
                  "templateId"
                ]
              },
              "example": {
                "nome": "Promo de outubro",
                "numeroId": "clx0numero000000000000001",
                "templateId": "clx0template0000000000001",
                "contatos": [
                  {
                    "telefone": "11987654321",
                    "nome": "Ana",
                    "variaveis": [
                      "Ana",
                      "COD-1042"
                    ]
                  },
                  {
                    "telefone": "11987654322",
                    "nome": "Bruno",
                    "variaveis": [
                      "Bruno",
                      "COD-1043"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Campanha criada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "nome": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "RASCUNHO",
                        "AGENDADA",
                        "EM_ANDAMENTO",
                        "PAUSADA",
                        "PAUSADA_AUTOMATICAMENTE",
                        "CONCLUIDA",
                        "CANCELADA"
                      ]
                    },
                    "numero": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "apelido": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "apelido"
                      ]
                    },
                    "template": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "nome": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nome"
                      ]
                    },
                    "lista": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "nome": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nome"
                      ]
                    },
                    "agendadaPara": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "iniciadaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "concluidaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "pausaAutomatica": {
                      "type": "boolean"
                    },
                    "motivoPausa": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "custoEstimadoCentavos": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer",
                      "description": "Contatos da campanha."
                    },
                    "totais": {
                      "type": "object",
                      "properties": {
                        "pendente": {
                          "type": "integer"
                        },
                        "enviado": {
                          "type": "integer"
                        },
                        "entregue": {
                          "type": "integer"
                        },
                        "lido": {
                          "type": "integer"
                        },
                        "respondido": {
                          "type": "integer"
                        },
                        "falhou": {
                          "type": "integer"
                        },
                        "ignoradoOptout": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "pendente",
                        "enviado",
                        "entregue",
                        "lido",
                        "respondido",
                        "falhou",
                        "ignoradoOptout"
                      ]
                    },
                    "alertas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "codigo": {
                            "type": "string"
                          },
                          "mensagem": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "codigo",
                          "mensagem"
                        ]
                      },
                      "description": "Informativos; nunca bloqueiam."
                    },
                    "taxaFalha": {
                      "type": "number",
                      "description": "Falhas ÷ (enviados + falhas), em %."
                    },
                    "erroMaisFrequente": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "codigo": {
                          "type": "string"
                        },
                        "mensagem": {
                          "type": "string"
                        },
                        "quantidade": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "codigo",
                        "mensagem",
                        "quantidade"
                      ]
                    },
                    "criadoEm": {
                      "type": "string"
                    },
                    "estimativa": {
                      "type": "object",
                      "properties": {
                        "categoria": {
                          "type": "string",
                          "enum": [
                            "MARKETING",
                            "UTILITY",
                            "AUTHENTICATION"
                          ]
                        },
                        "quantidade": {
                          "type": "integer",
                          "description": "Contatos que receberão (exclui opt-out)."
                        },
                        "ignoradosOptout": {
                          "type": "integer"
                        },
                        "centavos": {
                          "type": "integer",
                          "description": "Estimativa do que a Meta cobra, em centavos de BRL."
                        },
                        "porPais": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "ddi": {
                                "type": "string"
                              },
                              "rotulo": {
                                "type": "string"
                              },
                              "quantidade": {
                                "type": "integer"
                              },
                              "precoUsd": {
                                "type": "string"
                              },
                              "centavosPorMensagem": {
                                "type": "integer"
                              },
                              "centavos": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "ddi",
                              "rotulo",
                              "quantidade",
                              "precoUsd",
                              "centavosPorMensagem",
                              "centavos"
                            ]
                          }
                        },
                        "cambio": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "tabelaVersao": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "semPreco": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "estimado": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "categoria",
                        "quantidade",
                        "ignoradosOptout",
                        "centavos",
                        "porPais",
                        "cambio",
                        "tabelaVersao",
                        "semPreco",
                        "estimado"
                      ]
                    },
                    "contatos": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "recebidos": {
                          "type": "integer"
                        },
                        "aceitos": {
                          "type": "integer"
                        },
                        "rejeitados": {
                          "type": "integer"
                        },
                        "duplicados": {
                          "type": "integer"
                        },
                        "rejeitadasAmostra": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "linha": {
                                "type": "integer"
                              },
                              "telefone": {
                                "type": "string"
                              },
                              "motivo": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "linha",
                              "telefone",
                              "motivo"
                            ]
                          }
                        }
                      },
                      "required": [
                        "recebidos",
                        "aceitos",
                        "rejeitados",
                        "duplicados",
                        "rejeitadasAmostra"
                      ],
                      "description": "Resumo da importação quando a campanha foi criada com `contatos` inline."
                    }
                  },
                  "required": [
                    "id",
                    "nome",
                    "status",
                    "numero",
                    "template",
                    "lista",
                    "agendadaPara",
                    "iniciadaEm",
                    "concluidaEm",
                    "pausaAutomatica",
                    "motivoPausa",
                    "custoEstimadoCentavos",
                    "total",
                    "totais",
                    "alertas",
                    "taxaFalha",
                    "erroMaisFrequente",
                    "criadoEm",
                    "estimativa",
                    "contatos"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      },
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarCampanhas",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Lista as campanhas",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "RASCUNHO",
                "AGENDADA",
                "EM_ANDAMENTO",
                "PAUSADA",
                "PAUSADA_AUTOMATICAMENTE",
                "CONCLUIDA",
                "CANCELADA"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Campanhas da conta (até 200, mais recentes primeiro).",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campanhas": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "nome": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "RASCUNHO",
                              "AGENDADA",
                              "EM_ANDAMENTO",
                              "PAUSADA",
                              "PAUSADA_AUTOMATICAMENTE",
                              "CONCLUIDA",
                              "CANCELADA"
                            ]
                          },
                          "numero": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "apelido": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "apelido"
                            ]
                          },
                          "template": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "nome": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nome"
                            ]
                          },
                          "agendadaPara": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "iniciadaEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "concluidaEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "custoEstimadoCentavos": {
                            "type": "integer"
                          },
                          "total": {
                            "type": "integer"
                          },
                          "totais": {
                            "type": "object",
                            "properties": {
                              "pendente": {
                                "type": "integer"
                              },
                              "enviado": {
                                "type": "integer"
                              },
                              "entregue": {
                                "type": "integer"
                              },
                              "lido": {
                                "type": "integer"
                              },
                              "respondido": {
                                "type": "integer"
                              },
                              "falhou": {
                                "type": "integer"
                              },
                              "ignoradoOptout": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "pendente",
                              "enviado",
                              "entregue",
                              "lido",
                              "respondido",
                              "falhou",
                              "ignoradoOptout"
                            ]
                          },
                          "criadoEm": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "nome",
                          "status",
                          "numero",
                          "template",
                          "agendadaPara",
                          "iniciadaEm",
                          "concluidaEm",
                          "custoEstimadoCentavos",
                          "total",
                          "totais",
                          "criadoEm"
                        ]
                      }
                    }
                  },
                  "required": [
                    "campanhas"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/campanhas/{id}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterCampanha",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Status e totais de uma campanha",
        "description": "Totais por status do envio (pendente, enviado, entregue, lido, respondido, falhou, ignorado por opt-out), taxa de falha e o erro mais frequente.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da campanha."
            },
            "required": true,
            "description": "Identificador da campanha.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A campanha.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campanha"
                },
                "example": {
                  "id": "clx0campanha00000000000001",
                  "nome": "Promo de outubro",
                  "status": "EM_ANDAMENTO",
                  "numero": {
                    "id": "clx0numero000000000000001",
                    "apelido": "Oficial"
                  },
                  "template": {
                    "id": "clx0template0000000000001",
                    "nome": "promo_outubro"
                  },
                  "lista": {
                    "id": "clx0lista0000000000000001",
                    "nome": "Promo de outubro (API)"
                  },
                  "agendadaPara": null,
                  "iniciadaEm": "2026-10-14T13:00:00.000Z",
                  "concluidaEm": null,
                  "pausaAutomatica": false,
                  "motivoPausa": null,
                  "custoEstimadoCentavos": 10200,
                  "total": 3000,
                  "totais": {
                    "pendente": 2400,
                    "enviado": 600,
                    "entregue": 0,
                    "lido": 0,
                    "respondido": 0,
                    "falhou": 0,
                    "ignoradoOptout": 0
                  },
                  "alertas": [],
                  "taxaFalha": 0,
                  "erroMaisFrequente": null,
                  "criadoEm": "2026-10-14T13:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/campanhas/{id}/iniciar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "iniciarCampanha",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Inicia a campanha",
        "description": "Dispara uma campanha em rascunho ou agendada. Estado incompatível responde 409.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da campanha."
            },
            "required": true,
            "description": "Identificador da campanha.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A campanha atualizada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campanha"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/campanhas/{id}/pausar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "pausarCampanha",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Pausa a campanha",
        "description": "Para o envio: nenhum contato novo sai; os pendentes ficam guardados. Estado incompatível responde 409.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da campanha."
            },
            "required": true,
            "description": "Identificador da campanha.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A campanha atualizada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campanha"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/campanhas/{id}/retomar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "retomarCampanha",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Retoma a campanha",
        "description": "Continua dos pendentes (quem já foi enviado nunca é reenviado). Estado incompatível responde 409.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da campanha."
            },
            "required": true,
            "description": "Identificador da campanha.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A campanha atualizada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campanha"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/campanhas/{id}/cancelar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "cancelarCampanha",
        "tags": [
          "Templates e campanhas"
        ],
        "summary": "Cancela a campanha",
        "description": "Encerra a campanha; não pode ser retomada. Estado incompatível responde 409.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador da campanha."
            },
            "required": true,
            "description": "Identificador da campanha.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A campanha atualizada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campanha"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/leads": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarLeads",
        "tags": [
          "Leads"
        ],
        "summary": "Lista os leads",
        "description": "Filtros por status, origem, número, campanha, anúncio e período. Paginação por cursor (`proximoCursor` → `cursor`).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "NOVO",
                "REPASSADO",
                "EM_CONTATO",
                "RESPONDEU",
                "SEM_RESPOSTA",
                "DESCARTADO"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "CAMPANHA",
                "ANUNCIO",
                "ORGANICO"
              ]
            },
            "required": false,
            "name": "origem",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^c[a-z0-9]{20,30}$"
            },
            "required": false,
            "name": "numeroOficialId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^c[a-z0-9]{20,30}$"
            },
            "required": false,
            "name": "numeroAtribuidoId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^c[a-z0-9]{20,30}$"
            },
            "required": false,
            "name": "campanhaId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "required": false,
            "name": "anuncioId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40
            },
            "required": false,
            "name": "de",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40
            },
            "required": false,
            "name": "ate",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            },
            "required": false,
            "name": "limite",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Página de leads.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "itens": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "contatoTelefone": {
                            "type": "string"
                          },
                          "contatoNome": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "origem": {
                            "type": "string",
                            "enum": [
                              "CAMPANHA",
                              "ANUNCIO",
                              "ORGANICO"
                            ]
                          },
                          "campanha": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "nome": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nome"
                            ]
                          },
                          "anuncio": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "titulo": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "titulo",
                              "url"
                            ]
                          },
                          "primeiraMensagem": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "NOVO",
                              "REPASSADO",
                              "EM_CONTATO",
                              "RESPONDEU",
                              "SEM_RESPOSTA",
                              "DESCARTADO"
                            ]
                          },
                          "numeroOficial": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "apelido": {
                                "type": "string"
                              },
                              "telefone": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "apelido",
                              "telefone"
                            ]
                          },
                          "numeroAtribuido": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "apelido": {
                                "type": "string"
                              },
                              "telefone": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "apelido",
                              "telefone"
                            ]
                          },
                          "conversaId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "contatoOptout": {
                            "type": "boolean"
                          },
                          "repassadoEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "respondeuEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "criadoEm": {
                            "type": "string"
                          },
                          "economia": {
                            "type": "object",
                            "properties": {
                              "qtd": {
                                "type": "integer"
                              },
                              "marketingCentavos": {
                                "type": "integer"
                              },
                              "utilityCentavos": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "qtd",
                              "marketingCentavos",
                              "utilityCentavos"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "contatoTelefone",
                          "contatoNome",
                          "origem",
                          "campanha",
                          "anuncio",
                          "primeiraMensagem",
                          "status",
                          "numeroOficial",
                          "numeroAtribuido",
                          "conversaId",
                          "contatoOptout",
                          "repassadoEm",
                          "respondeuEm",
                          "criadoEm",
                          "economia"
                        ]
                      }
                    },
                    "proximoCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "itens",
                    "proximoCursor"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/leads/{id}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterLead",
        "tags": [
          "Leads"
        ],
        "summary": "Detalhe de um lead",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do lead."
            },
            "required": true,
            "description": "Identificador do lead.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O lead.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/leads/{id}/repassar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "repassarLead",
        "tags": [
          "Leads"
        ],
        "summary": "Repassa o lead a um número não oficial",
        "description": "Sem `numeroId` usa o rodízio da regra do número oficial; com `numeroId` repassa àquele número não oficial conectado. O ZapHub envia a mensagem de primeiro contato configurada. Contato em opt-out não bloqueia: vem sinalizado em `contatoOptout`. Já repassado: 409; descartado: 422.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do lead."
            },
            "required": true,
            "description": "Identificador do lead.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "numeroId": {
                    "type": "string",
                    "pattern": "^c[a-z0-9]{20,30}$"
                  }
                }
              },
              "example": {
                "numeroId": "clx0numero000000000000001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "O lead repassado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "lead": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "contatoTelefone": {
                          "type": "string"
                        },
                        "contatoNome": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "origem": {
                          "type": "string",
                          "enum": [
                            "CAMPANHA",
                            "ANUNCIO",
                            "ORGANICO"
                          ]
                        },
                        "campanha": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "nome": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "nome"
                          ]
                        },
                        "anuncio": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "titulo": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "id",
                            "titulo",
                            "url"
                          ]
                        },
                        "primeiraMensagem": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "NOVO",
                            "REPASSADO",
                            "EM_CONTATO",
                            "RESPONDEU",
                            "SEM_RESPOSTA",
                            "DESCARTADO"
                          ]
                        },
                        "numeroOficial": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "apelido": {
                              "type": "string"
                            },
                            "telefone": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "id",
                            "apelido",
                            "telefone"
                          ]
                        },
                        "numeroAtribuido": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "apelido": {
                              "type": "string"
                            },
                            "telefone": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "id",
                            "apelido",
                            "telefone"
                          ]
                        },
                        "conversaId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "contatoOptout": {
                          "type": "boolean"
                        },
                        "repassadoEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "respondeuEm": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "criadoEm": {
                          "type": "string"
                        },
                        "economia": {
                          "type": "object",
                          "properties": {
                            "qtd": {
                              "type": "integer"
                            },
                            "marketingCentavos": {
                              "type": "integer"
                            },
                            "utilityCentavos": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "qtd",
                            "marketingCentavos",
                            "utilityCentavos"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "contatoTelefone",
                        "contatoNome",
                        "origem",
                        "campanha",
                        "anuncio",
                        "primeiraMensagem",
                        "status",
                        "numeroOficial",
                        "numeroAtribuido",
                        "conversaId",
                        "contatoOptout",
                        "repassadoEm",
                        "respondeuEm",
                        "criadoEm",
                        "economia"
                      ]
                    },
                    "contatoOptout": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "lead",
                    "contatoOptout"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "409": {
            "$ref": "#/components/responses/Erro409"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/leads/{id}/descartar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "descartarLead",
        "tags": [
          "Leads"
        ],
        "summary": "Descarta o lead",
        "description": "Idempotente. Cancela um repasse automático pendente.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do lead."
            },
            "required": true,
            "description": "Identificador do lead.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O lead descartado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/economia": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterEconomia",
        "tags": [
          "Economia"
        ],
        "summary": "Economia do período",
        "description": "Os **mesmos totais do dashboard**, em centavos de BRL: `marketingCentavos` e `utilityCentavos` (o que as mensagens enviadas por números não oficiais custariam na API Oficial), o detalhamento por tipo de envio, o gasto estimado no oficial e a data da tabela de preços da Meta usada (`tabelaPrecos.vigenteDe`). Padrão: do primeiro dia do mês corrente até agora (America/Sao_Paulo).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40,
              "description": "Padrão: primeiro dia do mês corrente (America/Sao_Paulo)."
            },
            "required": false,
            "description": "Padrão: primeiro dia do mês corrente (America/Sao_Paulo).",
            "name": "inicio",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40,
              "description": "Padrão: agora."
            },
            "required": false,
            "description": "Padrão: agora.",
            "name": "fim",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "required": false,
            "name": "numeroId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Resumo da economia.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "periodo": {
                      "type": "object",
                      "properties": {
                        "inicio": {
                          "type": "string"
                        },
                        "fim": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "inicio",
                        "fim"
                      ],
                      "description": "Dias (America/Sao_Paulo), `AAAA-MM-DD`."
                    },
                    "numeroId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "totais": {
                      "type": "object",
                      "properties": {
                        "marketingCentavos": {
                          "type": "integer"
                        },
                        "utilityCentavos": {
                          "type": "integer"
                        },
                        "qtd": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "marketingCentavos",
                        "utilityCentavos",
                        "qtd"
                      ],
                      "description": "Os mesmos totais do dashboard, em centavos de BRL."
                    },
                    "porTipoEnvio": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "marketingCentavos": {
                            "type": "integer"
                          },
                          "utilityCentavos": {
                            "type": "integer"
                          },
                          "tipoEnvio": {
                            "type": "string",
                            "enum": [
                              "PRIMEIRO_CONTATO",
                              "PRIMEIRA_RESPOSTA",
                              "CONVERSA",
                              "RETOMADA",
                              "CONTATO_LEAD",
                              "AUTO_RESPOSTA",
                              "CAMPANHA",
                              "GRUPO"
                            ]
                          },
                          "qtd": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "marketingCentavos",
                          "utilityCentavos",
                          "tipoEnvio",
                          "qtd"
                        ]
                      }
                    },
                    "gastoOficial": {
                      "type": "object",
                      "properties": {
                        "centavos": {
                          "type": "integer"
                        },
                        "qtd": {
                          "type": "integer"
                        },
                        "porCategoria": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "categoria": {
                                "type": "string",
                                "enum": [
                                  "MARKETING",
                                  "UTILITY",
                                  "AUTHENTICATION"
                                ]
                              },
                              "qtd": {
                                "type": "integer"
                              },
                              "centavos": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "categoria",
                              "qtd",
                              "centavos"
                            ]
                          }
                        },
                        "estimado": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "centavos",
                        "qtd",
                        "porCategoria",
                        "estimado"
                      ]
                    },
                    "porOrigemLead": {
                      "type": "object",
                      "properties": {
                        "campanhas": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "marketingCentavos": {
                                "type": "integer"
                              },
                              "utilityCentavos": {
                                "type": "integer"
                              },
                              "campanhaId": {
                                "type": "string"
                              },
                              "nome": {
                                "type": "string"
                              },
                              "qtd": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "marketingCentavos",
                              "utilityCentavos",
                              "campanhaId",
                              "nome",
                              "qtd"
                            ]
                          }
                        },
                        "anuncios": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "marketingCentavos": {
                                "type": "integer"
                              },
                              "utilityCentavos": {
                                "type": "integer"
                              },
                              "anuncioId": {
                                "type": "string"
                              },
                              "titulo": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "qtd": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "marketingCentavos",
                              "utilityCentavos",
                              "anuncioId",
                              "titulo",
                              "qtd"
                            ]
                          }
                        }
                      },
                      "required": [
                        "campanhas",
                        "anuncios"
                      ]
                    },
                    "tabelaPrecos": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "versao": {
                          "type": "integer"
                        },
                        "vigenteDe": {
                          "type": "string",
                          "description": "Data da tabela de preços da Meta usada no cálculo."
                        },
                        "desatualizada": {
                          "type": "boolean"
                        },
                        "cambio": {
                          "type": "object",
                          "properties": {
                            "usdBrl": {
                              "type": "string"
                            },
                            "vigenteDe": {
                              "type": "string"
                            },
                            "fonte": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "usdBrl",
                            "vigenteDe",
                            "fonte"
                          ]
                        }
                      },
                      "required": [
                        "versao",
                        "vigenteDe",
                        "desatualizada",
                        "cambio"
                      ]
                    }
                  },
                  "required": [
                    "periodo",
                    "numeroId",
                    "totais",
                    "porTipoEnvio",
                    "gastoOficial",
                    "porOrigemLead",
                    "tabelaPrecos"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/destinos-eventos": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarDestinos",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Lista os destinos",
        "description": "Até 5 por conta. Segredos saem sempre mascarados. Chave restrita a números não gerencia destinos (403): é configuração da conta inteira.",
        "responses": {
          "200": {
            "description": "Destinos.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "destinos": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "tipo": {
                            "type": "string",
                            "enum": [
                              "WEBHOOK",
                              "RABBITMQ",
                              "NATS",
                              "KAFKA",
                              "SQS"
                            ]
                          },
                          "nome": {
                            "type": "string"
                          },
                          "ativo": {
                            "type": "boolean"
                          },
                          "eventos": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "mensagem.recebida",
                                "mensagem.enviada",
                                "mensagem.status",
                                "numero.status",
                                "numero.qrcode",
                                "contato.optout",
                                "campanha.status",
                                "lead.criado",
                                "lead.repassado",
                                "lead.status",
                                "mensagem.reacao",
                                "mensagem.editada",
                                "mensagem.apagada",
                                "mensagem.voto",
                                "contato.digitando",
                                "contato.presenca",
                                "contato.atualizado",
                                "chamada.recebida",
                                "chamada.encerrada",
                                "numero.banido",
                                "historico.sincronizado",
                                "grupo.atualizado",
                                "grupo.participantes",
                                "grupo.entrou",
                                "etiqueta.alterada",
                                "etiqueta.aplicada",
                                "canal.seguido",
                                "canal.deixado",
                                "evolution.bruto"
                              ]
                            }
                          },
                          "numeroIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Vazio = todos os números."
                          },
                          "config": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "url": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "url"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "host": {
                                    "type": "string"
                                  },
                                  "port": {
                                    "type": "integer"
                                  },
                                  "vhost": {
                                    "type": "string"
                                  },
                                  "usuario": {
                                    "type": "string",
                                    "description": "Mascarado."
                                  },
                                  "senha": {
                                    "type": "string",
                                    "description": "Sempre mascarada."
                                  },
                                  "exchange": {
                                    "type": "string"
                                  },
                                  "prefixo": {
                                    "type": "string"
                                  },
                                  "tls": {
                                    "type": "boolean"
                                  },
                                  "permitirSemTls": {
                                    "type": "boolean"
                                  },
                                  "modo": {
                                    "type": "string",
                                    "enum": [
                                      "exchange",
                                      "filas"
                                    ]
                                  }
                                },
                                "required": [
                                  "host",
                                  "port",
                                  "vhost",
                                  "usuario",
                                  "senha",
                                  "exchange",
                                  "prefixo",
                                  "tls",
                                  "permitirSemTls",
                                  "modo"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "servidores": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "tls": {
                                    "type": "boolean"
                                  },
                                  "permitirSemTls": {
                                    "type": "boolean"
                                  },
                                  "autenticacao": {
                                    "type": "string",
                                    "enum": [
                                      "nenhuma",
                                      "token",
                                      "usuario",
                                      "creds"
                                    ]
                                  },
                                  "usuario": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Mascarado."
                                  },
                                  "senha": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Sempre mascarada."
                                  },
                                  "prefixo": {
                                    "type": "string"
                                  },
                                  "jetstream": {
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "servidores",
                                  "tls",
                                  "permitirSemTls",
                                  "autenticacao",
                                  "usuario",
                                  "senha",
                                  "prefixo",
                                  "jetstream"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "brokers": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "tls": {
                                    "type": "boolean"
                                  },
                                  "permitirSemTls": {
                                    "type": "boolean"
                                  },
                                  "sasl": {
                                    "type": "string",
                                    "enum": [
                                      "nenhum",
                                      "plain",
                                      "scram-sha-256",
                                      "scram-sha-512"
                                    ]
                                  },
                                  "usuario": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Mascarado."
                                  },
                                  "senha": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Sempre mascarada."
                                  },
                                  "topico": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "prefixoTopico": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "brokers",
                                  "tls",
                                  "permitirSemTls",
                                  "sasl",
                                  "usuario",
                                  "senha",
                                  "topico",
                                  "prefixoTopico"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "filaUrl": {
                                    "type": "string"
                                  },
                                  "regiao": {
                                    "type": "string"
                                  },
                                  "fifo": {
                                    "type": "boolean"
                                  },
                                  "accessKeyId": {
                                    "type": "string",
                                    "description": "Mascarado."
                                  },
                                  "secretAccessKey": {
                                    "type": "string",
                                    "description": "Sempre mascarado."
                                  }
                                },
                                "required": [
                                  "filaUrl",
                                  "regiao",
                                  "fifo",
                                  "accessKeyId",
                                  "secretAccessKey"
                                ]
                              }
                            ]
                          },
                          "segredoHmac": {
                            "type": "string",
                            "description": "Segredo de assinatura MASCARADO. O completo só aparece na criação/rotação."
                          },
                          "criadoEm": {
                            "type": "string"
                          },
                          "atualizadoEm": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "tipo",
                          "nome",
                          "ativo",
                          "eventos",
                          "numeroIds",
                          "config",
                          "segredoHmac",
                          "criadoEm",
                          "atualizadoEm"
                        ]
                      }
                    }
                  },
                  "required": [
                    "destinos"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      },
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "criarDestino",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Cria um destino (webhook, RabbitMQ, NATS, Kafka ou SQS)",
        "description": "Todos os tipos usam o mesmo envelope, assinatura HMAC, ordem por número e reenvio (até 6 tentativas em 24h). Hosts internos são recusados no cadastro e a cada entrega, e TLS é exigido por padrão.\n\n- `WEBHOOK`: URL **HTTPS** pública; assinatura no header `X-ZapHub-Signature`.\n- `RABBITMQ`: broker do cliente. `modo: \"exchange\"` só publica (routing key `<prefixo>.<evento>`); `modo: \"filas\"` declara uma fila durável por evento (`<prefixo>.<evento>`) e nunca a apaga.\n- `NATS`: assunto `<prefixo>.<contaId>.<numeroId>.<evento>` (eventos sem número usam `conta`); `jetstream: true` aguarda o ack do stream e deduplica por `Nats-Msg-Id`.\n- `KAFKA`: `topico` único ou `prefixoTopico` (um tópico por evento: `<prefixoTopico>-mensagem-recebida`); chave = `numeroId` (ordem por número); o ZapHub não cria tópicos.\n- `SQS`: URL da fila (a região sai dela); em fila `.fifo`, `MessageGroupId` = número e `MessageDeduplicationId` = `id` do evento. Corpo acima de 256 KB falha sem reenvio.\n\nO segredo HMAC completo vem em `segredoHmacRevelado` **uma única vez**; use-o para verificar a assinatura. Chave restrita a números não gerencia destinos (403): é configuração da conta inteira.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`."
            },
            "required": false,
            "description": "Chave de idempotência (até 255 caracteres ASCII; ex.: um UUID). A repetição da mesma requisição em até 24h devolve a resposta original sem executar de novo (header `Idempotent-Replayed: true`). A mesma chave com corpo diferente retorna 422 `idempotencia_corpo_diferente`.",
            "name": "Idempotency-Key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "tipo": {
                        "type": "string",
                        "enum": [
                          "WEBHOOK"
                        ]
                      },
                      "nome": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "ativo": {
                        "type": "boolean",
                        "default": true
                      },
                      "eventos": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "mensagem.recebida",
                            "mensagem.enviada",
                            "mensagem.status",
                            "numero.status",
                            "numero.qrcode",
                            "contato.optout",
                            "campanha.status",
                            "lead.criado",
                            "lead.repassado",
                            "lead.status",
                            "mensagem.reacao",
                            "mensagem.editada",
                            "mensagem.apagada",
                            "mensagem.voto",
                            "contato.digitando",
                            "contato.presenca",
                            "contato.atualizado",
                            "chamada.recebida",
                            "chamada.encerrada",
                            "numero.banido",
                            "historico.sincronizado",
                            "grupo.atualizado",
                            "grupo.participantes",
                            "grupo.entrou",
                            "etiqueta.alterada",
                            "etiqueta.aplicada",
                            "canal.seguido",
                            "canal.deixado",
                            "evolution.bruto"
                          ]
                        },
                        "minItems": 1,
                        "maxItems": 29
                      },
                      "numeroIds": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "maxItems": 100,
                        "default": []
                      },
                      "url": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 2048
                      }
                    },
                    "required": [
                      "tipo",
                      "nome",
                      "eventos",
                      "url"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tipo": {
                        "type": "string",
                        "enum": [
                          "RABBITMQ"
                        ]
                      },
                      "nome": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "ativo": {
                        "type": "boolean",
                        "default": true
                      },
                      "eventos": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "mensagem.recebida",
                            "mensagem.enviada",
                            "mensagem.status",
                            "numero.status",
                            "numero.qrcode",
                            "contato.optout",
                            "campanha.status",
                            "lead.criado",
                            "lead.repassado",
                            "lead.status",
                            "mensagem.reacao",
                            "mensagem.editada",
                            "mensagem.apagada",
                            "mensagem.voto",
                            "contato.digitando",
                            "contato.presenca",
                            "contato.atualizado",
                            "chamada.recebida",
                            "chamada.encerrada",
                            "numero.banido",
                            "historico.sincronizado",
                            "grupo.atualizado",
                            "grupo.participantes",
                            "grupo.entrou",
                            "etiqueta.alterada",
                            "etiqueta.aplicada",
                            "canal.seguido",
                            "canal.deixado",
                            "evolution.bruto"
                          ]
                        },
                        "minItems": 1,
                        "maxItems": 29
                      },
                      "numeroIds": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "maxItems": 100,
                        "default": []
                      },
                      "uri": {
                        "type": "string",
                        "maxLength": 2048,
                        "pattern": "^amqps?:\\/\\/"
                      },
                      "host": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 253
                      },
                      "port": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 65535
                      },
                      "vhost": {
                        "type": "string",
                        "maxLength": 255
                      },
                      "usuario": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 255
                      },
                      "senha": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 1024
                      },
                      "tls": {
                        "type": "boolean"
                      },
                      "exchange": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 255,
                        "pattern": "^[A-Za-z0-9_.:\\-]+$"
                      },
                      "prefixo": {
                        "type": "string",
                        "maxLength": 64,
                        "pattern": "^([A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)?$",
                        "default": "zaphub"
                      },
                      "permitirSemTls": {
                        "type": "boolean",
                        "default": false
                      },
                      "modo": {
                        "type": "string",
                        "enum": [
                          "exchange",
                          "filas"
                        ],
                        "default": "exchange"
                      }
                    },
                    "required": [
                      "tipo",
                      "nome",
                      "eventos",
                      "exchange"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tipo": {
                        "type": "string",
                        "enum": [
                          "NATS"
                        ]
                      },
                      "nome": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "ativo": {
                        "type": "boolean",
                        "default": true
                      },
                      "eventos": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "mensagem.recebida",
                            "mensagem.enviada",
                            "mensagem.status",
                            "numero.status",
                            "numero.qrcode",
                            "contato.optout",
                            "campanha.status",
                            "lead.criado",
                            "lead.repassado",
                            "lead.status",
                            "mensagem.reacao",
                            "mensagem.editada",
                            "mensagem.apagada",
                            "mensagem.voto",
                            "contato.digitando",
                            "contato.presenca",
                            "contato.atualizado",
                            "chamada.recebida",
                            "chamada.encerrada",
                            "numero.banido",
                            "historico.sincronizado",
                            "grupo.atualizado",
                            "grupo.participantes",
                            "grupo.entrou",
                            "etiqueta.alterada",
                            "etiqueta.aplicada",
                            "canal.seguido",
                            "canal.deixado",
                            "evolution.bruto"
                          ]
                        },
                        "minItems": 1,
                        "maxItems": 29
                      },
                      "numeroIds": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "maxItems": 100,
                        "default": []
                      },
                      "servidores": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 3,
                          "maxLength": 300,
                          "pattern": "^((nats|tls):\\/\\/)?(\\[[0-9a-fA-F:]+\\]|[A-Za-z0-9.-]+):\\d{1,5}$"
                        },
                        "minItems": 1,
                        "maxItems": 5
                      },
                      "tls": {
                        "type": "boolean",
                        "default": true
                      },
                      "permitirSemTls": {
                        "type": "boolean",
                        "default": false
                      },
                      "autenticacao": {
                        "type": "string",
                        "enum": [
                          "nenhuma",
                          "token",
                          "usuario",
                          "creds"
                        ],
                        "default": "nenhuma"
                      },
                      "usuario": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 255
                      },
                      "senha": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 8192
                      },
                      "prefixo": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "pattern": "^[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*$",
                        "default": "zaphub"
                      },
                      "jetstream": {
                        "type": "boolean",
                        "default": false
                      }
                    },
                    "required": [
                      "tipo",
                      "nome",
                      "eventos",
                      "servidores"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tipo": {
                        "type": "string",
                        "enum": [
                          "KAFKA"
                        ]
                      },
                      "nome": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "ativo": {
                        "type": "boolean",
                        "default": true
                      },
                      "eventos": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "mensagem.recebida",
                            "mensagem.enviada",
                            "mensagem.status",
                            "numero.status",
                            "numero.qrcode",
                            "contato.optout",
                            "campanha.status",
                            "lead.criado",
                            "lead.repassado",
                            "lead.status",
                            "mensagem.reacao",
                            "mensagem.editada",
                            "mensagem.apagada",
                            "mensagem.voto",
                            "contato.digitando",
                            "contato.presenca",
                            "contato.atualizado",
                            "chamada.recebida",
                            "chamada.encerrada",
                            "numero.banido",
                            "historico.sincronizado",
                            "grupo.atualizado",
                            "grupo.participantes",
                            "grupo.entrou",
                            "etiqueta.alterada",
                            "etiqueta.aplicada",
                            "canal.seguido",
                            "canal.deixado",
                            "evolution.bruto"
                          ]
                        },
                        "minItems": 1,
                        "maxItems": 29
                      },
                      "numeroIds": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "maxItems": 100,
                        "default": []
                      },
                      "brokers": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 3,
                          "maxLength": 300,
                          "pattern": "^(\\[[0-9a-fA-F:]+\\]|[A-Za-z0-9.-]+):\\d{1,5}$"
                        },
                        "minItems": 1,
                        "maxItems": 10
                      },
                      "tls": {
                        "type": "boolean",
                        "default": true
                      },
                      "permitirSemTls": {
                        "type": "boolean",
                        "default": false
                      },
                      "sasl": {
                        "type": "string",
                        "enum": [
                          "nenhum",
                          "plain",
                          "scram-sha-256",
                          "scram-sha-512"
                        ],
                        "default": "nenhum"
                      },
                      "usuario": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 255
                      },
                      "senha": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 1024
                      },
                      "topico": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "pattern": "^[A-Za-z0-9._-]+$"
                      },
                      "prefixoTopico": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "pattern": "^[A-Za-z0-9._-]+$"
                      }
                    },
                    "required": [
                      "tipo",
                      "nome",
                      "eventos",
                      "brokers"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tipo": {
                        "type": "string",
                        "enum": [
                          "SQS"
                        ]
                      },
                      "nome": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "ativo": {
                        "type": "boolean",
                        "default": true
                      },
                      "eventos": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "mensagem.recebida",
                            "mensagem.enviada",
                            "mensagem.status",
                            "numero.status",
                            "numero.qrcode",
                            "contato.optout",
                            "campanha.status",
                            "lead.criado",
                            "lead.repassado",
                            "lead.status",
                            "mensagem.reacao",
                            "mensagem.editada",
                            "mensagem.apagada",
                            "mensagem.voto",
                            "contato.digitando",
                            "contato.presenca",
                            "contato.atualizado",
                            "chamada.recebida",
                            "chamada.encerrada",
                            "numero.banido",
                            "historico.sincronizado",
                            "grupo.atualizado",
                            "grupo.participantes",
                            "grupo.entrou",
                            "etiqueta.alterada",
                            "etiqueta.aplicada",
                            "canal.seguido",
                            "canal.deixado",
                            "evolution.bruto"
                          ]
                        },
                        "minItems": 1,
                        "maxItems": 29
                      },
                      "numeroIds": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "maxItems": 100,
                        "default": []
                      },
                      "filaUrl": {
                        "type": "string",
                        "maxLength": 300,
                        "pattern": "^https:\\/\\/sqs\\.([a-z]{2}(?:-gov)?-[a-z]+-\\d)\\.amazonaws\\.com\\/(\\d{12})\\/([A-Za-z0-9_-]{1,80}(?:\\.fifo)?)$"
                      },
                      "accessKeyId": {
                        "type": "string",
                        "pattern": "^[A-Z0-9]{16,128}$"
                      },
                      "secretAccessKey": {
                        "type": "string",
                        "minLength": 16,
                        "maxLength": 256
                      }
                    },
                    "required": [
                      "tipo",
                      "nome",
                      "eventos",
                      "filaUrl",
                      "accessKeyId",
                      "secretAccessKey"
                    ]
                  }
                ]
              },
              "example": {
                "tipo": "WEBHOOK",
                "nome": "Meu CRM",
                "url": "https://crm.exemplo.com.br/hooks/zaphub",
                "eventos": [
                  "mensagem.recebida",
                  "mensagem.status",
                  "lead.criado"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Destino criado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "WEBHOOK",
                        "RABBITMQ",
                        "NATS",
                        "KAFKA",
                        "SQS"
                      ]
                    },
                    "nome": {
                      "type": "string"
                    },
                    "ativo": {
                      "type": "boolean"
                    },
                    "eventos": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "mensagem.recebida",
                          "mensagem.enviada",
                          "mensagem.status",
                          "numero.status",
                          "numero.qrcode",
                          "contato.optout",
                          "campanha.status",
                          "lead.criado",
                          "lead.repassado",
                          "lead.status",
                          "mensagem.reacao",
                          "mensagem.editada",
                          "mensagem.apagada",
                          "mensagem.voto",
                          "contato.digitando",
                          "contato.presenca",
                          "contato.atualizado",
                          "chamada.recebida",
                          "chamada.encerrada",
                          "numero.banido",
                          "historico.sincronizado",
                          "grupo.atualizado",
                          "grupo.participantes",
                          "grupo.entrou",
                          "etiqueta.alterada",
                          "etiqueta.aplicada",
                          "canal.seguido",
                          "canal.deixado",
                          "evolution.bruto"
                        ]
                      }
                    },
                    "numeroIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Vazio = todos os números."
                    },
                    "config": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "url"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "host": {
                              "type": "string"
                            },
                            "port": {
                              "type": "integer"
                            },
                            "vhost": {
                              "type": "string"
                            },
                            "usuario": {
                              "type": "string",
                              "description": "Mascarado."
                            },
                            "senha": {
                              "type": "string",
                              "description": "Sempre mascarada."
                            },
                            "exchange": {
                              "type": "string"
                            },
                            "prefixo": {
                              "type": "string"
                            },
                            "tls": {
                              "type": "boolean"
                            },
                            "permitirSemTls": {
                              "type": "boolean"
                            },
                            "modo": {
                              "type": "string",
                              "enum": [
                                "exchange",
                                "filas"
                              ]
                            }
                          },
                          "required": [
                            "host",
                            "port",
                            "vhost",
                            "usuario",
                            "senha",
                            "exchange",
                            "prefixo",
                            "tls",
                            "permitirSemTls",
                            "modo"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "servidores": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "tls": {
                              "type": "boolean"
                            },
                            "permitirSemTls": {
                              "type": "boolean"
                            },
                            "autenticacao": {
                              "type": "string",
                              "enum": [
                                "nenhuma",
                                "token",
                                "usuario",
                                "creds"
                              ]
                            },
                            "usuario": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Mascarado."
                            },
                            "senha": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Sempre mascarada."
                            },
                            "prefixo": {
                              "type": "string"
                            },
                            "jetstream": {
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "servidores",
                            "tls",
                            "permitirSemTls",
                            "autenticacao",
                            "usuario",
                            "senha",
                            "prefixo",
                            "jetstream"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "brokers": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "tls": {
                              "type": "boolean"
                            },
                            "permitirSemTls": {
                              "type": "boolean"
                            },
                            "sasl": {
                              "type": "string",
                              "enum": [
                                "nenhum",
                                "plain",
                                "scram-sha-256",
                                "scram-sha-512"
                              ]
                            },
                            "usuario": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Mascarado."
                            },
                            "senha": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Sempre mascarada."
                            },
                            "topico": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "prefixoTopico": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "brokers",
                            "tls",
                            "permitirSemTls",
                            "sasl",
                            "usuario",
                            "senha",
                            "topico",
                            "prefixoTopico"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "filaUrl": {
                              "type": "string"
                            },
                            "regiao": {
                              "type": "string"
                            },
                            "fifo": {
                              "type": "boolean"
                            },
                            "accessKeyId": {
                              "type": "string",
                              "description": "Mascarado."
                            },
                            "secretAccessKey": {
                              "type": "string",
                              "description": "Sempre mascarado."
                            }
                          },
                          "required": [
                            "filaUrl",
                            "regiao",
                            "fifo",
                            "accessKeyId",
                            "secretAccessKey"
                          ]
                        }
                      ]
                    },
                    "segredoHmac": {
                      "type": "string",
                      "description": "Segredo de assinatura MASCARADO. O completo só aparece na criação/rotação."
                    },
                    "criadoEm": {
                      "type": "string"
                    },
                    "atualizadoEm": {
                      "type": "string"
                    },
                    "segredoHmacRevelado": {
                      "type": "string",
                      "description": "Segredo HMAC completo: exibido UMA vez (criação ou rotação). Guarde-o."
                    }
                  },
                  "required": [
                    "id",
                    "tipo",
                    "nome",
                    "ativo",
                    "eventos",
                    "numeroIds",
                    "config",
                    "segredoHmac",
                    "criadoEm",
                    "atualizadoEm"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "422": {
            "$ref": "#/components/responses/Erro422"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/destinos-eventos/entregas/{entregaId}/reenviar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "reenviarEntrega",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Reenvia uma entrega",
        "description": "Reenvio manual de uma entrega (útil depois que as 6 tentativas falharam).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "`id` da entrega, de `GET /v1/destinos-eventos/{id}/entregas`."
            },
            "required": true,
            "description": "`id` da entrega, de `GET /v1/destinos-eventos/{id}/entregas`.",
            "name": "entregaId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "A entrega reenfileirada.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "eventoId": {
                      "type": "string"
                    },
                    "evento": {
                      "type": "string"
                    },
                    "sequencia": {
                      "type": "integer"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "PENDENTE",
                        "ENTREGUE",
                        "NAO_ROTEADA",
                        "FALHOU"
                      ]
                    },
                    "tentativas": {
                      "type": "integer"
                    },
                    "proximaTentativaEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "ultimoErro": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "entregueEm": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "criadoEm": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "eventoId",
                    "evento",
                    "sequencia",
                    "status",
                    "tentativas",
                    "proximaTentativaEm",
                    "ultimoErro",
                    "entregueEm",
                    "criadoEm"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/destinos-eventos/{id}": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "obterDestino",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Detalhe de um destino",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do destino."
            },
            "required": true,
            "description": "Identificador do destino.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "O destino.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DestinoEvento"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      },
      "patch": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "atualizarDestino",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Atualiza um destino",
        "description": "Todos os campos são opcionais; o `tipo` não muda. `rotacionarSegredo: true` gera um novo segredo HMAC (devolvido uma vez).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do destino."
            },
            "required": true,
            "description": "Identificador do destino.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nome": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "ativo": {
                    "type": "boolean"
                  },
                  "eventos": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "mensagem.recebida",
                        "mensagem.enviada",
                        "mensagem.status",
                        "numero.status",
                        "numero.qrcode",
                        "contato.optout",
                        "campanha.status",
                        "lead.criado",
                        "lead.repassado",
                        "lead.status",
                        "mensagem.reacao",
                        "mensagem.editada",
                        "mensagem.apagada",
                        "mensagem.voto",
                        "contato.digitando",
                        "contato.presenca",
                        "contato.atualizado",
                        "chamada.recebida",
                        "chamada.encerrada",
                        "numero.banido",
                        "historico.sincronizado",
                        "grupo.atualizado",
                        "grupo.participantes",
                        "grupo.entrou",
                        "etiqueta.alterada",
                        "etiqueta.aplicada",
                        "canal.seguido",
                        "canal.deixado",
                        "evolution.bruto"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 29
                  },
                  "numeroIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64
                    },
                    "maxItems": 100
                  },
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048
                  },
                  "uri": {
                    "type": "string",
                    "maxLength": 2048,
                    "pattern": "^amqps?:\\/\\/"
                  },
                  "host": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "port": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 65535
                  },
                  "vhost": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "usuario": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "senha": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192
                  },
                  "tls": {
                    "type": "boolean"
                  },
                  "exchange": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "pattern": "^[A-Za-z0-9_.:\\-]+$"
                  },
                  "prefixo": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "permitirSemTls": {
                    "type": "boolean"
                  },
                  "modo": {
                    "type": "string",
                    "enum": [
                      "exchange",
                      "filas"
                    ]
                  },
                  "servidores": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 3,
                      "maxLength": 300,
                      "pattern": "^((nats|tls):\\/\\/)?(\\[[0-9a-fA-F:]+\\]|[A-Za-z0-9.-]+):\\d{1,5}$"
                    },
                    "minItems": 1,
                    "maxItems": 5
                  },
                  "autenticacao": {
                    "type": "string",
                    "enum": [
                      "nenhuma",
                      "token",
                      "usuario",
                      "creds"
                    ]
                  },
                  "jetstream": {
                    "type": "boolean"
                  },
                  "brokers": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 3,
                      "maxLength": 300,
                      "pattern": "^(\\[[0-9a-fA-F:]+\\]|[A-Za-z0-9.-]+):\\d{1,5}$"
                    },
                    "minItems": 1,
                    "maxItems": 10
                  },
                  "sasl": {
                    "type": "string",
                    "enum": [
                      "nenhum",
                      "plain",
                      "scram-sha-256",
                      "scram-sha-512"
                    ]
                  },
                  "topico": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "minLength": 1,
                    "maxLength": 200,
                    "pattern": "^[A-Za-z0-9._-]+$"
                  },
                  "prefixoTopico": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "minLength": 1,
                    "maxLength": 200,
                    "pattern": "^[A-Za-z0-9._-]+$"
                  },
                  "filaUrl": {
                    "type": "string",
                    "maxLength": 300,
                    "pattern": "^https:\\/\\/sqs\\.([a-z]{2}(?:-gov)?-[a-z]+-\\d)\\.amazonaws\\.com\\/(\\d{12})\\/([A-Za-z0-9_-]{1,80}(?:\\.fifo)?)$"
                  },
                  "accessKeyId": {
                    "type": "string",
                    "pattern": "^[A-Z0-9]{16,128}$"
                  },
                  "secretAccessKey": {
                    "type": "string",
                    "minLength": 16,
                    "maxLength": 256
                  },
                  "rotacionarSegredo": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "ativo": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "O destino atualizado.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "tipo": {
                      "type": "string",
                      "enum": [
                        "WEBHOOK",
                        "RABBITMQ",
                        "NATS",
                        "KAFKA",
                        "SQS"
                      ]
                    },
                    "nome": {
                      "type": "string"
                    },
                    "ativo": {
                      "type": "boolean"
                    },
                    "eventos": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "mensagem.recebida",
                          "mensagem.enviada",
                          "mensagem.status",
                          "numero.status",
                          "numero.qrcode",
                          "contato.optout",
                          "campanha.status",
                          "lead.criado",
                          "lead.repassado",
                          "lead.status",
                          "mensagem.reacao",
                          "mensagem.editada",
                          "mensagem.apagada",
                          "mensagem.voto",
                          "contato.digitando",
                          "contato.presenca",
                          "contato.atualizado",
                          "chamada.recebida",
                          "chamada.encerrada",
                          "numero.banido",
                          "historico.sincronizado",
                          "grupo.atualizado",
                          "grupo.participantes",
                          "grupo.entrou",
                          "etiqueta.alterada",
                          "etiqueta.aplicada",
                          "canal.seguido",
                          "canal.deixado",
                          "evolution.bruto"
                        ]
                      }
                    },
                    "numeroIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Vazio = todos os números."
                    },
                    "config": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "url"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "host": {
                              "type": "string"
                            },
                            "port": {
                              "type": "integer"
                            },
                            "vhost": {
                              "type": "string"
                            },
                            "usuario": {
                              "type": "string",
                              "description": "Mascarado."
                            },
                            "senha": {
                              "type": "string",
                              "description": "Sempre mascarada."
                            },
                            "exchange": {
                              "type": "string"
                            },
                            "prefixo": {
                              "type": "string"
                            },
                            "tls": {
                              "type": "boolean"
                            },
                            "permitirSemTls": {
                              "type": "boolean"
                            },
                            "modo": {
                              "type": "string",
                              "enum": [
                                "exchange",
                                "filas"
                              ]
                            }
                          },
                          "required": [
                            "host",
                            "port",
                            "vhost",
                            "usuario",
                            "senha",
                            "exchange",
                            "prefixo",
                            "tls",
                            "permitirSemTls",
                            "modo"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "servidores": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "tls": {
                              "type": "boolean"
                            },
                            "permitirSemTls": {
                              "type": "boolean"
                            },
                            "autenticacao": {
                              "type": "string",
                              "enum": [
                                "nenhuma",
                                "token",
                                "usuario",
                                "creds"
                              ]
                            },
                            "usuario": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Mascarado."
                            },
                            "senha": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Sempre mascarada."
                            },
                            "prefixo": {
                              "type": "string"
                            },
                            "jetstream": {
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "servidores",
                            "tls",
                            "permitirSemTls",
                            "autenticacao",
                            "usuario",
                            "senha",
                            "prefixo",
                            "jetstream"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "brokers": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "tls": {
                              "type": "boolean"
                            },
                            "permitirSemTls": {
                              "type": "boolean"
                            },
                            "sasl": {
                              "type": "string",
                              "enum": [
                                "nenhum",
                                "plain",
                                "scram-sha-256",
                                "scram-sha-512"
                              ]
                            },
                            "usuario": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Mascarado."
                            },
                            "senha": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Sempre mascarada."
                            },
                            "topico": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "prefixoTopico": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "brokers",
                            "tls",
                            "permitirSemTls",
                            "sasl",
                            "usuario",
                            "senha",
                            "topico",
                            "prefixoTopico"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "filaUrl": {
                              "type": "string"
                            },
                            "regiao": {
                              "type": "string"
                            },
                            "fifo": {
                              "type": "boolean"
                            },
                            "accessKeyId": {
                              "type": "string",
                              "description": "Mascarado."
                            },
                            "secretAccessKey": {
                              "type": "string",
                              "description": "Sempre mascarado."
                            }
                          },
                          "required": [
                            "filaUrl",
                            "regiao",
                            "fifo",
                            "accessKeyId",
                            "secretAccessKey"
                          ]
                        }
                      ]
                    },
                    "segredoHmac": {
                      "type": "string",
                      "description": "Segredo de assinatura MASCARADO. O completo só aparece na criação/rotação."
                    },
                    "criadoEm": {
                      "type": "string"
                    },
                    "atualizadoEm": {
                      "type": "string"
                    },
                    "segredoHmacRevelado": {
                      "type": "string",
                      "description": "Segredo HMAC completo: exibido UMA vez (criação ou rotação). Guarde-o."
                    }
                  },
                  "required": [
                    "id",
                    "tipo",
                    "nome",
                    "ativo",
                    "eventos",
                    "numeroIds",
                    "config",
                    "segredoHmac",
                    "criadoEm",
                    "atualizadoEm"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      },
      "delete": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "removerDestino",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Remove um destino",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do destino."
            },
            "required": true,
            "description": "Identificador do destino.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "204": {
            "description": "Removido.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/destinos-eventos/{id}/testar": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "testarDestino",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Testa a conexão",
        "description": "Publica um evento `teste.ping` e mostra o resultado, ou o erro exato (autenticação, vhost, TLS, timeout, status HTTP).",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do destino."
            },
            "required": true,
            "description": "Identificador do destino.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Resultado do teste.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sucesso": {
                      "type": "boolean"
                    },
                    "statusHttp": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "latenciaMs": {
                      "type": "integer"
                    },
                    "erro": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "aviso": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "sucesso",
                    "statusHttp",
                    "latenciaMs",
                    "erro",
                    "aviso"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/destinos-eventos/{id}/entregas": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "listarEntregas",
        "tags": [
          "Destinos de eventos"
        ],
        "summary": "Log de entregas",
        "description": "Entregas do destino com status (`PENDENTE`, `ENTREGUE`, `NAO_ROTEADA`, `FALHOU`), tentativas e o último erro.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Identificador do destino."
            },
            "required": true,
            "description": "Identificador do destino.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "required": false,
            "name": "pagina",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "required": false,
            "name": "limite",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "PENDENTE",
                "ENTREGUE",
                "NAO_ROTEADA",
                "FALHOU"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Página de entregas.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "itens": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "eventoId": {
                            "type": "string"
                          },
                          "evento": {
                            "type": "string"
                          },
                          "sequencia": {
                            "type": "integer"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "PENDENTE",
                              "ENTREGUE",
                              "NAO_ROTEADA",
                              "FALHOU"
                            ]
                          },
                          "tentativas": {
                            "type": "integer"
                          },
                          "proximaTentativaEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ultimoErro": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "entregueEm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "criadoEm": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "eventoId",
                          "evento",
                          "sequencia",
                          "status",
                          "tentativas",
                          "proximaTentativaEm",
                          "ultimoErro",
                          "entregueEm",
                          "criadoEm"
                        ]
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "pagina": {
                      "type": "integer"
                    },
                    "limite": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "itens",
                    "total",
                    "pagina",
                    "limite"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/eventos/catalogo": {
      "get": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "catalogoEventos",
        "tags": [
          "Eventos ao vivo"
        ],
        "summary": "Catálogo de eventos",
        "description": "Eventos disponíveis (com os tipos de número em que ocorrem e a versão do formato), tipos de destino aceitos e a URL do WebSocket.",
        "responses": {
          "200": {
            "description": "Catálogo.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eventos": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "nome": {
                            "type": "string",
                            "enum": [
                              "mensagem.recebida",
                              "mensagem.enviada",
                              "mensagem.status",
                              "numero.status",
                              "numero.qrcode",
                              "contato.optout",
                              "campanha.status",
                              "lead.criado",
                              "lead.repassado",
                              "lead.status",
                              "mensagem.reacao",
                              "mensagem.editada",
                              "mensagem.apagada",
                              "mensagem.voto",
                              "contato.digitando",
                              "contato.presenca",
                              "contato.atualizado",
                              "chamada.recebida",
                              "chamada.encerrada",
                              "numero.banido",
                              "historico.sincronizado",
                              "grupo.atualizado",
                              "grupo.participantes",
                              "grupo.entrou",
                              "etiqueta.alterada",
                              "etiqueta.aplicada",
                              "canal.seguido",
                              "canal.deixado",
                              "evolution.bruto"
                            ]
                          },
                          "descricao": {
                            "type": "string"
                          },
                          "tiposNumero": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "OFICIAL",
                                "NAO_OFICIAL"
                              ]
                            },
                            "description": "Tipos de número em que o evento ocorre."
                          },
                          "versao": {
                            "type": "integer",
                            "description": "Versão do formato de `dados`."
                          }
                        },
                        "required": [
                          "nome",
                          "descricao",
                          "tiposNumero",
                          "versao"
                        ]
                      }
                    },
                    "tiposDestino": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "WEBHOOK",
                          "RABBITMQ",
                          "NATS",
                          "KAFKA",
                          "SQS"
                        ]
                      }
                    },
                    "websocket": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "URL da conexão WebSocket de eventos."
                        }
                      },
                      "required": [
                        "url"
                      ]
                    }
                  },
                  "required": [
                    "eventos",
                    "tiposDestino",
                    "websocket"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    },
    "/v1/eventos/ws/ticket": {
      "post": {
        "security": [
          {
            "ChaveApi": []
          }
        ],
        "operationId": "ticketWebSocket",
        "tags": [
          "Eventos ao vivo"
        ],
        "summary": "Ticket para o WebSocket",
        "description": "Ticket de **uso único**, válido por 60s, para abrir `wss://api.zaphub.wssengenharia.com.br/v1/eventos/ws?ticket=<ticket>` a partir do navegador (que não envia headers no WebSocket). Servidores podem conectar direto com o header `Authorization: Bearer <chave>`. A chave de API **nunca** vai na URL.\n\nDepois de conectar, envie `{\"tipo\":\"assinar\",\"eventos\":[...],\"numeroIds\":[...],\"desde\":\"<id do último evento>\"}` (todos os campos opcionais). O servidor responde `{\"tipo\":\"assinado\"}`, reenvia os eventos posteriores a `desde` (até 24h) e segue ao vivo, um envelope por mensagem. Ping a cada 25s; até 5 conexões por chave (a sexta fecha com o código 4429). Entrega \"melhor esforço\": para garantia, use um destino.",
        "responses": {
          "201": {
            "description": "Ticket.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ticket": {
                      "type": "string",
                      "description": "Uso único. Conecte em `/v1/eventos/ws?ticket=<ticket>`."
                    },
                    "expiraEmSegundos": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "ticket",
                    "expiraEmSegundos"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "402": {
            "$ref": "#/components/responses/Erro402"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          }
        }
      }
    }
  },
  "webhooks": {
    "mensagem.recebida": {
      "post": {
        "operationId": "evento_mensagem_recebida",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.recebida",
        "description": "Mensagem recebida em um número.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.recebida`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.recebida`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.recebida",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem0000000000001",
                  "conversaId": "clx0conversa0000000000001",
                  "numero": "clx0numero000000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "origem": "CONTATO",
                  "direcao": "ENTRADA",
                  "tipoConteudo": "TEXTO",
                  "texto": "Oi, queria saber o preço",
                  "midia": null,
                  "localizacao": null,
                  "contato": {
                    "telefone": "5511987654321",
                    "nome": "Ana"
                  },
                  "ocorridaEm": "2026-10-14T13:02:11.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "mensagem.enviada": {
      "post": {
        "operationId": "evento_mensagem_enviada",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.enviada",
        "description": "Mensagem enviada (pela API, pelo painel, automática ou pelo celular).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.enviada`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.enviada`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.enviada",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem0000000000001",
                  "conversaId": "clx0conversa0000000000001",
                  "numeroId": "clx0numero000000000000001",
                  "leadId": null,
                  "para": "5511987654321",
                  "tipoNumero": "NAO_OFICIAL",
                  "tipoEnvio": "PRIMEIRO_CONTATO",
                  "origem": "API",
                  "tipoConteudo": "TEXTO",
                  "texto": "Olá!",
                  "idExterno": "3EB0A1B2C3",
                  "enviadoEm": "2026-10-14T13:02:11.000Z",
                  "enfileirada": false,
                  "contatoOptout": false,
                  "janelaAberta": false,
                  "custoEvitado": {
                    "marketingCentavos": 34,
                    "utilityCentavos": 7
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "mensagem.status": {
      "post": {
        "operationId": "evento_mensagem_status",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.status",
        "description": "Mudança de status (enviada, entregue, lida, falhou). Em `falhou` traz `erro` com o código e a mensagem da Meta.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.status`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.status`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.status",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem0000000000001",
                  "numeroId": "clx0numero000000000000001",
                  "status": "falhou",
                  "ocorridoEm": "2026-10-14T13:02:12.000Z",
                  "erro": {
                    "codigo": "janela_fechada",
                    "codigoExterno": "131047",
                    "mensagem": "Passaram mais de 24 horas desde a última mensagem do contato. Envie um template aprovado para retomar a conversa."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "numero.status": {
      "post": {
        "operationId": "evento_numero_status",
        "tags": [
          "Eventos"
        ],
        "summary": "numero.status",
        "description": "Conectado, desconectado, erro, restrito…\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.numero.status`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.numero.status`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "numero.status",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numeroId": "clx0numero000000000000001",
                  "tipo": "NAO_OFICIAL",
                  "apelido": "Vendas",
                  "status": "CONECTADO",
                  "telefone": "5511987654321",
                  "nomePerfil": "Loja Exemplo",
                  "ocorridoEm": "2026-10-14T13:02:11.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "numero.qrcode": {
      "post": {
        "operationId": "evento_numero_qrcode",
        "tags": [
          "Eventos"
        ],
        "summary": "numero.qrcode",
        "description": "QR renovado durante o pareamento (`codigo` é o texto do QR; `qrcode`, a imagem, quando disponível).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.numero.qrcode`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.numero.qrcode`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "numero.qrcode",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numeroId": "clx0numero000000000000001",
                  "codigo": "2@abc…",
                  "qrcode": "data:image/png;base64,…",
                  "expiraEm": "2026-10-14T13:04:11.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "contato.optout": {
      "post": {
        "operationId": "evento_contato_optout",
        "tags": [
          "Eventos"
        ],
        "summary": "contato.optout",
        "description": "O contato pediu para não receber mais mensagens (SAIR, PARAR, STOP…).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.contato.optout`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.contato.optout`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "contato.optout",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "telefone": "5511987654321",
                  "numero": "clx0numero000000000000001"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "campanha.status": {
      "post": {
        "operationId": "evento_campanha_status",
        "tags": [
          "Eventos"
        ],
        "summary": "campanha.status",
        "description": "Mudança de estado de uma campanha, com os totais.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.campanha.status`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.campanha.status`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "campanha.status",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "campanhaId": "clx0campanha00000000000001",
                  "nome": "Promo de outubro",
                  "numeroId": "clx0numero000000000000001",
                  "status": "CONCLUIDA",
                  "motivo": null,
                  "total": 3000,
                  "taxaFalha": 0.4,
                  "custoEstimadoCentavos": 10200,
                  "ocorridoEm": "2026-10-14T13:20:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "lead.criado": {
      "post": {
        "operationId": "evento_lead_criado",
        "tags": [
          "Eventos"
        ],
        "summary": "lead.criado",
        "description": "Novo lead captado pelo número oficial.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.lead.criado`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.lead.criado`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "lead.criado",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "leadId": "clx0lead000000000000000001",
                  "status": "NOVO",
                  "origem": "CAMPANHA",
                  "contato": {
                    "telefone": "5511987654321",
                    "nome": "Ana"
                  },
                  "numeroOficialId": "clx0numero000000000000001",
                  "numeroAtribuido": null,
                  "campanha": {
                    "id": "clx0campanha00000000000001",
                    "nome": "Promo de outubro"
                  },
                  "primeiraMensagem": "Quero saber mais",
                  "criadoEm": "2026-10-14T13:02:11.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "lead.repassado": {
      "post": {
        "operationId": "evento_lead_repassado",
        "tags": [
          "Eventos"
        ],
        "summary": "lead.repassado",
        "description": "Lead repassado a um número não oficial.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.lead.repassado`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.lead.repassado`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "lead.repassado",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "leadId": "clx0lead000000000000000001",
                  "status": "REPASSADO",
                  "statusAnterior": "NOVO",
                  "origem": "CAMPANHA",
                  "numeroAtribuido": {
                    "id": "clx0numero000000000000001",
                    "telefone": "5511987654321",
                    "apelido": "Comercial"
                  },
                  "repassadoEm": "2026-10-14T13:03:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "lead.status": {
      "post": {
        "operationId": "evento_lead_status",
        "tags": [
          "Eventos"
        ],
        "summary": "lead.status",
        "description": "Mudança de status do lead (respondeu, sem resposta, descartado…).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.lead.status`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.lead.status`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "lead.status",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "leadId": "clx0lead000000000000000001",
                  "status": "RESPONDEU",
                  "statusAnterior": "REPASSADO",
                  "respondeuEm": "2026-10-14T13:10:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "mensagem.reacao": {
      "post": {
        "operationId": "evento_mensagem_reacao",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.reacao",
        "description": "Reação a uma mensagem, do contato ou do próprio número (`emoji` vazio = reação removida). `mensagemId` é nulo se a mensagem não está no histórico. Números oficiais e não oficiais.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.reacao`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.reacao`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.reacao",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem00000000000001",
                  "idExternoAlvo": "3EB0C5A277F7F9B6C599",
                  "conversaId": "clx0conversa00000000000001",
                  "numero": "clx0numero000000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "autor": "contato",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "emoji": "👍",
                  "ocorridaEm": "2026-10-14T13:05:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "mensagem.editada": {
      "post": {
        "operationId": "evento_mensagem_editada",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.editada",
        "description": "O autor editou uma mensagem de texto (números não oficiais). A mensagem guardada passa a ter o texto novo. `textoNovo` é nulo quando a mensagem original não está no histórico (o WhatsApp manda a edição criptografada com a chave da original).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.editada`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.editada`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.editada",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem00000000000001",
                  "idExternoAlvo": "3EB0C5A277F7F9B6C599",
                  "conversaId": "clx0conversa00000000000001",
                  "numero": "clx0numero000000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "autor": "contato",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "textoNovo": "Quero 3 unidades",
                  "editadaEm": "2026-10-14T13:06:00.000Z",
                  "ocorridaEm": "2026-10-14T13:06:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "mensagem.apagada": {
      "post": {
        "operationId": "evento_mensagem_apagada",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.apagada",
        "description": "O autor apagou a mensagem para todos (números não oficiais). Texto e mídia são limpos; o download passa a responder 410.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.apagada`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.apagada`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.apagada",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem00000000000001",
                  "idExternoAlvo": "3EB0C5A277F7F9B6C599",
                  "conversaId": "clx0conversa00000000000001",
                  "numero": "clx0numero000000000000001",
                  "tipoNumero": "NAO_OFICIAL",
                  "autor": "contato",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "apagadaEm": "2026-10-14T13:07:00.000Z",
                  "ocorridaEm": "2026-10-14T13:07:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "mensagem.voto": {
      "post": {
        "operationId": "evento_mensagem_voto",
        "tags": [
          "Eventos"
        ],
        "summary": "mensagem.voto",
        "description": "Um contato votou, trocou o voto ou retirou o voto (`opcoes` vazio) numa enquete enviada pelo número (números não oficiais). O resultado consolidado está em `GET /v1/mensagens/{id}/votos`.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.mensagem.voto`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.mensagem.voto`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "mensagem.voto",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "mensagemId": "clx0mensagem00000000000001",
                  "conversaId": "clx0conversa00000000000001",
                  "numero": "clx0numero000000000000001",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "opcoes": [
                    "Sexta-feira"
                  ],
                  "votadoEm": "2026-10-14T13:07:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "contato.digitando": {
      "post": {
        "operationId": "evento_contato_digitando",
        "tags": [
          "Eventos"
        ],
        "summary": "contato.digitando",
        "description": "O contato está digitando, gravando áudio ou parou (`estado`). Efêmero: reenvio curto, sem caixa de entrada. Só é assinado no Evolution quando algum destino ou WebSocket o pede. O WhatsApp só informa a digitação a números que estão online e com conversa já registrada no ZapHub.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.contato.digitando`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.contato.digitando`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "contato.digitando",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "estado": "digitando"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "contato.presenca": {
      "post": {
        "operationId": "evento_contato_presenca",
        "tags": [
          "Eventos"
        ],
        "summary": "contato.presenca",
        "description": "O contato ficou online ou offline (conforme a privacidade dele e só para contatos com conversa ativa). Efêmero.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.contato.presenca`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.contato.presenca`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "contato.presenca",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "online": false,
                  "vistoPorUltimoEm": "2026-10-14T12:58:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "contato.atualizado": {
      "post": {
        "operationId": "evento_contato_atualizado",
        "tags": [
          "Eventos"
        ],
        "summary": "contato.atualizado",
        "description": "O contato mudou nome público, foto ou recado. Só os campos que mudaram vêm preenchidos.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.contato.atualizado`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.contato.atualizado`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "contato.atualizado",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "conversaId": "clx0conversa00000000000001",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "nome": "Carlos S."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "chamada.recebida": {
      "post": {
        "operationId": "evento_chamada_recebida",
        "tags": [
          "Eventos"
        ],
        "summary": "chamada.recebida",
        "description": "O número recebeu uma chamada. Chamadas recusadas automaticamente pela configuração do número não geram evento.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.chamada.recebida`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.chamada.recebida`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "chamada.recebida",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "chamadaId": "B1C4F2A9E0",
                  "numero": "clx0numero000000000000001",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "video": false,
                  "recebidaEm": "2026-10-14T13:08:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "chamada.encerrada": {
      "post": {
        "operationId": "evento_chamada_encerrada",
        "tags": [
          "Eventos"
        ],
        "summary": "chamada.encerrada",
        "description": "Uma chamada terminou (`motivo` como o WhatsApp informa).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.chamada.encerrada`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.chamada.encerrada`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "chamada.encerrada",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "chamadaId": "B1C4F2A9E0",
                  "numero": "clx0numero000000000000001",
                  "contato": {
                    "telefone": "5511987654321"
                  },
                  "motivo": "timeout",
                  "encerradaEm": "2026-10-14T13:08:40.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "numero.banido": {
      "post": {
        "operationId": "evento_numero_banido",
        "tags": [
          "Eventos"
        ],
        "summary": "numero.banido",
        "description": "O WhatsApp aplicou banimento temporário ao número. Também sai `numero.status` (DESCONECTADO, motivo `banido`) e o OWNER é avisado.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.numero.banido`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.numero.banido`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "numero.banido",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "codigo": "SENT_TO_TOO_MANY_PEOPLE",
                  "expiraEm": "2026-10-15T13:00:00.000Z",
                  "ocorridoEm": "2026-10-14T13:00:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "historico.sincronizado": {
      "post": {
        "operationId": "evento_historico_sincronizado",
        "tags": [
          "Eventos"
        ],
        "summary": "historico.sincronizado",
        "description": "O celular concluiu uma etapa de sincronização de histórico. As mensagens do histórico não entram na caixa de entrada (assine `evolution.bruto` para o conteúdo). Efêmero.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.historico.sincronizado`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.historico.sincronizado`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "historico.sincronizado",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "tipo": "RECENT",
                  "progresso": 100,
                  "conversas": 42,
                  "mensagens": 1380
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "grupo.atualizado": {
      "post": {
        "operationId": "evento_grupo_atualizado",
        "tags": [
          "Eventos"
        ],
        "summary": "grupo.atualizado",
        "description": "Nome, descrição ou configurações de um grupo mudaram (no WhatsApp ou pela API).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.grupo.atualizado`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.grupo.atualizado`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "grupo.atualizado",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "grupo": {
                    "id": "clx0grupo00000000000000001",
                    "nome": "Clientes VIP"
                  },
                  "nome": "Clientes VIP",
                  "descricao": "Ofertas da semana",
                  "soAdminsEnviam": true,
                  "soAdminsEditam": true,
                  "alteradoPor": "5511987654321"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "grupo.participantes": {
      "post": {
        "operationId": "evento_grupo_participantes",
        "tags": [
          "Eventos"
        ],
        "summary": "grupo.participantes",
        "description": "Participantes entraram, saíram, foram promovidos ou rebaixados. `numeroSaiu: true` quando o próprio número saiu ou foi removido.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.grupo.participantes`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.grupo.participantes`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "grupo.participantes",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "grupo": {
                    "id": "clx0grupo00000000000000001",
                    "nome": "Clientes VIP"
                  },
                  "entraram": [
                    "5511987654321"
                  ],
                  "sairam": [],
                  "promovidos": [],
                  "rebaixados": [],
                  "numeroSaiu": false
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "grupo.entrou": {
      "post": {
        "operationId": "evento_grupo_entrou",
        "tags": [
          "Eventos"
        ],
        "summary": "grupo.entrou",
        "description": "O número entrou num grupo (convite, link ou grupo criado por ele).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.grupo.entrou`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.grupo.entrou`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "grupo.entrou",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "grupo": {
                    "id": "clx0grupo00000000000000001",
                    "nome": "Clientes VIP"
                  },
                  "motivo": "invite"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "etiqueta.alterada": {
      "post": {
        "operationId": "evento_etiqueta_alterada",
        "tags": [
          "Eventos"
        ],
        "summary": "etiqueta.alterada",
        "description": "Uma etiqueta do WhatsApp Business foi criada, editada (`acao: salva`) ou removida (`acao: removida`), no celular ou pela API.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.etiqueta.alterada`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.etiqueta.alterada`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "etiqueta.alterada",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "etiqueta": {
                    "id": "clx0etiqueta0000000000001",
                    "nome": "Pagamento pendente",
                    "cor": 3
                  },
                  "acao": "salva"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "etiqueta.aplicada": {
      "post": {
        "operationId": "evento_etiqueta_aplicada",
        "tags": [
          "Eventos"
        ],
        "summary": "etiqueta.aplicada",
        "description": "Uma etiqueta foi aplicada (`aplicada: true`) ou tirada de uma conversa ou mensagem pelo celular.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.etiqueta.aplicada`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.etiqueta.aplicada`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "etiqueta.aplicada",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "etiqueta": {
                    "id": "clx0etiqueta0000000000001",
                    "nome": "Pagamento pendente",
                    "cor": 3
                  },
                  "alvo": "conversa",
                  "aplicada": true,
                  "conversaId": "clx0conversa00000000000001",
                  "mensagemId": null,
                  "contato": {
                    "telefone": "5511987654321"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "canal.seguido": {
      "post": {
        "operationId": "evento_canal_seguido",
        "tags": [
          "Eventos"
        ],
        "summary": "canal.seguido",
        "description": "O número passou a seguir um canal (newsletter), pelo celular.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.canal.seguido`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.canal.seguido`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "canal.seguido",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "canal": {
                    "id": "120363100000000001@newsletter",
                    "nome": "Ofertas da Loja"
                  },
                  "papel": "subscriber"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "canal.deixado": {
      "post": {
        "operationId": "evento_canal_deixado",
        "tags": [
          "Eventos"
        ],
        "summary": "canal.deixado",
        "description": "O número deixou de seguir um canal (newsletter).\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.canal.deixado`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.canal.deixado`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "canal.deixado",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "canal": {
                    "id": "120363100000000001@newsletter",
                    "nome": null
                  },
                  "papel": "guest"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    },
    "evolution.bruto": {
      "post": {
        "operationId": "evento_evolution_bruto",
        "tags": [
          "Eventos"
        ],
        "summary": "evolution.bruto",
        "description": "Evento original do Evolution Go (números não oficiais), sem credenciais e sem base64 (`midiaDisponivel: true`). **O formato de `payload` acompanha a versão do Evolution e pode mudar.** Payload acima de 200 KB sai só com `payloadTruncado: true`.\n\nEntregue em webhook (`POST` com o header `X-ZapHub-Signature: t=<unix>,v1=<hex>`) publicado no RabbitMQ (routing key `<prefixo>.evolution.bruto`), NATS (assunto `<prefixo>.<contaId>.<numeroId>.evolution.bruto`), Kafka ou SQS do cliente, e no WebSocket `/v1/eventos/ws`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnvelopeEvento"
              },
              "example": {
                "id": "clx0evento00000000000000001",
                "evento": "evolution.bruto",
                "ocorridoEm": "2026-10-14T13:02:11.000Z",
                "contaId": "clx0conta000000000000000001",
                "numeroId": "clx0numero000000000000001",
                "sequencia": 4812,
                "dados": {
                  "numero": "clx0numero000000000000001",
                  "eventoOriginal": "Message",
                  "payload": {
                    "Info": {
                      "ID": "3EB0C5A277F7F9B6C599",
                      "Chat": "5511987654321@s.whatsapp.net"
                    },
                    "Message": {
                      "conversation": "Olá!"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Responda qualquer 2xx para confirmar. Outro status (ou timeout) agenda nova tentativa: backoff exponencial, até 6 em 24h."
          }
        }
      }
    }
  }
}
