# APIFacil WhatsApp API > Plataforma SaaS de API WhatsApp multi-instancia. Backend Laravel + microservicos TypeScript (Baileys) + Redis + MySQL. ## Base URL Producao: `https://apifacil.dev/api/v1` Desenvolvimento: `http://localhost:8001/api/v1` ## Autenticacao Todas as rotas (exceto `/whatsapp/qrcode/{token}`) exigem o token de API no header Authorization (sem prefixo "Bearer"): ``` Authorization: {seu_token_de_api} ``` Nao use `Authorization: Bearer {token}` — o middleware valida o token direto, sem prefixo. Se enviar "Bearer ..." retorna 401. Tokens sao gerados no painel do usuario. Rate limiting aplicado em todos os endpoints via middleware `verificarLimiteRequisicoes`. ## Especificacao Formal - **OpenAPI 3.1**: `https://apifacil.dev/openapi.json` — spec completa para gerar clients automaticamente (Swagger, Postman, curl, etc). - **Documentacao HTML**: `https://apifacil.dev/documentacao/whatsapp` ## 3 Modalidades de Conexao ### 1. QR Code (tradicional) Fluxo: `POST /whatsapp/instancia/{id}/iniciar` -> poll `GET /whatsapp/instancia/{id}/qrcode` -> escanear com celular. Ideal para onboarding presencial, web apps com camera, fluxo manual. QR Code expira em ~60s. Chame /iniciar novamente para gerar novo. Cliente abre: Configuracoes > Aparelhos conectados > Conectar aparelho. ### 2. Pairing Code (telefone) `POST /whatsapp/instancia/{id}/solicitar-pareamento` com body `{"telefone":"5511999999999"}`. Retorna `pairing_code` (8 caracteres alfanumericos, ex: W4NQJMRD, expira em 120s). Limpa credenciais antigas (close-session tipo=2) e inicia sessao automaticamente (start-session) ANTES de pedir o codigo ao WhatsApp — NAO chame /iniciar antes, conflita com a sessao recem-iniciada. Cliente digita no celular: Configuracoes > Aparelhos conectados > Conectar com codigo de telefone. Telefone: DDI+DDD+numero, apenas digitos, 10 a 15 chars. Regex: ^\d{10,15}$. Poll de status: `GET /whatsapp/instancia/{id}/status` -> status_banco="connected". Consultar codigo atual no Redis: `GET /whatsapp/instancia/{id}/codigo-pareamento` -> {pairing_code, expirado}. Se expirou: chame /solicitar-pareamento novamente (NAO use /codigo-pareamento para gerar novo — ele so consulta). Ideal para: integracoes server-to-server, onboarding remoto sem camera, apps mobile. ### 3. Importar Sessao (WebAuth) `POST /whatsapp/instancia/{id}/importar-sessao` com body `{"session_data":""}`. A sessao conecta automaticamente apos importacao — NAO chame /iniciar. JSON gerado pela extensao WhatsApp Session Extractor (Chrome/Firefox), max 512KB. Campos obrigatorios validados: identityKey.private, identityKey.public, account.details, account.accountSignatureKey, registrationId (numerico), noiseCandidates (array nao vazio), signedPreKey.private, signedPreKey.signature. Ideal para: migrar sessao WhatsApp Web ja logada para a API sem re-escanear, onboarding sem celular em maos. Atencao: apos importar, NAO use WhatsApp Web no mesmo navegador (WhatsApp detecta sessao duplicada e desloga). Desconecte WhatsApp Web no celular antes de importar. Se instancia ja conectada: chame POST /{id}/desconectar antes. ## Endpoints por Categoria ### Instancias | Metodo | Path | Descricao | |--------|------|-----------| | POST | `/whatsapp/instancia/criar` | Criar instancia | | GET | `/whatsapp/instancia/listar` | Listar instancias | | GET | `/whatsapp/instancia/{id}/detalhes` | Detalhes (aceita ID ou codigo) | | GET | `/whatsapp/instancia/{id}/status` | Status atual | | DELETE | `/whatsapp/instancia/{id}` | Deletar instancia | | POST | `/whatsapp/instancia/verificar-numero` | Verificar se numero tem WhatsApp (cache 1 dia) | | POST | `/whatsapp/instancia/{id}/foto-perfil` | Obter foto de perfil de contato | ### Conexao | Metodo | Path | Descricao | |--------|------|-----------| | POST | `/whatsapp/instancia/{id}/iniciar` | Iniciar sessao (gera QR Code) | | GET | `/whatsapp/instancia/{id}/qrcode` | Obter QR Code (base64) | | GET | `/whatsapp/instancia/{id}/qrcode/image` | Obter QR Code (JPG) | | POST | `/whatsapp/instancia/{id}/solicitar-pareamento` | Solicitar Pairing Code | | GET | `/whatsapp/instancia/{id}/codigo-pareamento` | Obter codigo atual | | POST | `/whatsapp/instancia/{id}/importar-sessao` | Importar sessao (WebAuth) | | POST | `/whatsapp/instancia/{id}/pausar` | Pausar sessao (mantem credenciais) | | POST | `/whatsapp/instancia/{id}/desconectar` | Desconectar (remove credenciais) | ### Mensagens | Metodo | Path | Descricao | |--------|------|-----------| | POST | `/whatsapp/enviar-mensagem` | Texto | | POST | `/whatsapp/enviar-foto` | Imagem via URL | | POST | `/whatsapp/enviar-foto-64` | Imagem em base64 | | POST | `/whatsapp/enviar-arquivo` | Arquivo via URL | | POST | `/whatsapp/enviar-arquivo-64` | Arquivo em base64 | | POST | `/whatsapp/enviar-audio` | Audio via URL (MP3/OGG) | | POST | `/whatsapp/enviar-audio-64` | Audio em base64 (MP3/OGG/WebM) | | POST | `/whatsapp/enviar-video` | Video via URL | | POST | `/whatsapp/enviar-preview` | Mensagem com preview de link | | POST | `/whatsapp/enviar-botao` | Mensagem com botao interativo | | POST | `/whatsapp/enviar-localizacao` | Localizacao (lat/lng) | | POST | `/whatsapp/apagar-mensagem` | Apagar mensagem enviada | ### Grupos | Metodo | Path | Descricao | |--------|------|-----------| | GET | `/whatsapp/grupos` | Listar grupos | | POST | `/whatsapp/grupo/enviar-mensagem` | Mensagem para grupo | | POST | `/whatsapp/grupo/enviar-arquivo` | Arquivo para grupo | | POST | `/whatsapp/grupo/enviar-preview` | Preview para grupo | ### Configuracoes | Metodo | Path | Descricao | |--------|------|-----------| | PUT | `/whatsapp/configuracao/{id}` | Atualizar webhooks/config | ### Notificacoes | Metodo | Path | Descricao | |--------|------|-----------| | GET | `/whatsapp/notificacoes` | Listar (paginado, com filtros) | | GET | `/whatsapp/notificacoes/{id}` | Detalhes (com historico webhook) | | POST | `/whatsapp/notificacao/reprocessar-webhook` | Reenviar webhook | ### Publico (sem auth) | Metodo | Path | Descricao | |--------|------|-----------| | GET | `/whatsapp/qrcode/{token}` | QR Code publico via public_token | ## Response Padrao Todas as respostas seguem o formato: ```json { "error": false, "message": "Mensagem descritiva", "data": { ... } } ``` Erros: `error: true`, `message` com descricao, HTTP status code apropriado (400, 401, 403, 404, 422, 500). ## Webhooks Configurados via `PUT /whatsapp/configuracao/{id}` (apenas planos pagos). O microservico envia POST para sua URL com Content-Type: application/json e User-Agent: API Facil/1.0, timeout 10s. ### URLs de webhook (roteamento) - `webhook_url` — mensagens privadas + eventos de interacao (lido/respondido/reproduzido) - `webhook_grupo` — mensagens de grupo - `webhook_ativo` — master switch (false desliga TODOS os webhooks) - `webhook_status` — existe no banco mas NAO e usado para envio (apenas webhook_url e webhook_grupo recebem POST) ### Evento 1: whatsapp_insert (mensagem enviada/recebida) Disparado para todo evento de mensagem. Roteado para webhook_url (privado) ou webhook_grupo (grupo). Payload: { event: "whatsapp_insert", id, message_id, instancia_id, instancia_codigo, mensagem, caption, origem, destino, enviado, erro, tipo_envio, grupo, lido, respondido, reproduzido, status, origem_chamada, created_at, pushName, is_business, remote_jid, remote_jid_alt, participant, participant_alt, jid_contato, eh_lid, numero_telefone_origem, numero_telefone_destino, numero_origem_lid, numero_destino_lid, addressing_mode, responder_para } tipo_envio valores: MENSAGEM_ENVIADA, MENSAGEM_RECEBIDA, MENSAGEM_ERRO, IMAGEM_ENVIADA, AUDIO_ENVIADO, VIDEO_ENVIADO, DOCUMENTO_ENVIADO, BOTAO_ENVIADO, LOCALIZACAO_ENVIADA, MENSAGEM_GRUPO_RECEBIDO, MENSAGEM_GRUPO_ENVIADO. ### Evento 2: whatsapp_update (interacao) Disparado quando mensagem marcada como lido, respondida ou reproduzida. Sempre para webhook_url. Desativar: set ativar_atualizacoes_interacao=false no config_json. Payload: { event: "whatsapp_update", id, mensagem_id, instancia_id, codigo, mensagem, origem, destino, tipo_envio, grupo, respondido, lido, reproduzido, erro, enviado, origem_chamada, numero_origem_lid, numero_destino_lid, is_business, created_at, updated_at } ### Retry (apenas whatsapp_insert) 1 imediato + 3 retries em 1min, 5min, 30min (total 4 tentativas em ~36min). Cron do microservico processa ate 50/rodada. Apos falha na 4a tentativa: marca erro permanente. Reenvio manual: POST /whatsapp/notificacao/reprocessar-webhook com body {"id": 12345}. whatsapp_update NAO tem retry (so 1 tentativa). ### Receptor Seu receptor deve responder 2xx em ate 10s (timeout do remetente). Processamento pesado deve ser assincrono. Headers enviados: User-Agent: API Facil/1.0, Content-Type: application/json. ## Planos e Recursos | Recurso | Plano Free | Plano Pago | |---------|-----------|------------| | Mensagens de texto | Sim | Sim | | Webhooks | Nao | Sim | | Envio de imagens | Nao | Sim | | Envio de videos | Nao | Sim | | Envio de arquivos | Nao | Sim | | Envio de audios | Nao | Sim | | Botoes interativos | Nao | Sim | ## Formatos de Telefone - Com DDI+DDD+numero: `5511999999999` (apenas digitos, 10 a 15) - JID de grupo: `120363000000@g.us` - Identificadores especiais sao aceitos em alguns endpoints (LID) ## Filas e Processamento Mensagens sao enfileiradas em Redis e processadas assincronamente. O response retorna imediatamente com `notificacao_id`. Para saber se foi entregue, consulte `GET /whatsapp/notificacoes/{id}`. ## Links - OpenAPI JSON: `/openapi.json` - Documentacao HTML: `/documentacao/whatsapp` - Painel: `https://apifacil.dev/login` - Suporte: `suporte@apifacil.dev`