WhatsApp API
API REST para envio programático de mensagens e ficheiros via WhatsApp. Suporte completo a texto, imagens, vídeos, áudio, documentos e PDFs através de sessões WhatsApp activas. Cada resposta inclui o message_id gerado pelo protocolo WhatsApp.
Envie texto, imagens (JPEG, PNG, WEBP, GIF), vídeo (MP4), áudio (OGG, MP3, AAC), documentos (DOCX, XLSX) e PDFs. Um único endpoint com o campo type controla o tipo de envio.
POST /whatsapp/send/upload aceita ficheiro local por multipart/form-data e entrega ao destinatário numa única chamada HTTP. Recomendado para envios únicos.
POST /whatsapp/upload armazena o ficheiro nos servidores MozeSMS e devolve um URL permanente — ideal para enviar o mesmo ficheiro a múltiplos números sem repetir o upload.
Envie média por URL pública, URL MozeSMS ou data:image/jpeg;base64,… inline. O tipo é detectado pelos bytes mágicos do ficheiro — a extensão é ignorada.
Autenticação
Todos os endpoints exigem autenticação por Bearer token no header Authorization. O token é obtido via POST /auth/login e tem validade de 24 horas (expires_in: 86400).
1. Obter token de acesso
POST /auth/login
Content-Type: application/json
{
"email": "utilizador@empresa.com",
"password": "sua_senha"
}
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 86400
}
2. Usar o token nos pedidos
Inclua o token em todas as chamadas à API no header Authorization:
JWT devolvido por POST /auth/login. Válido 24 h. Após expirar, re-autentique — os endpoints devolvem 401 Unauthorized com token inválido ou expirado.
UUID da sessão WhatsApp activa (distinto do token de auth). Obtenha no painel em Sessões. Obrigatório em todos os endpoints de envio. Ex: 17c6074e-3359-4a73-a513-a35953a007f2.
Pedidos multipart/form-data exigem o header Referer: https://meudominio.com. Sem ele, o WAF (regra CWAF 211180) devolve 403 Forbidden antes de chegar à API.
Campo phone: código do país + número, sem + nem espaços. Exemplos: 258845888195 (MZ), 351912345678 (PT), 5511987654321 (BR).
Erros & Limites
A WhatsApp API usa códigos HTTP convencionais. Erros devolvem sempre um objeto JSON com success: false e uma mensagem descritiva no campo error.
| Código | Significado |
|---|---|
| 200 | Operação realizada com sucesso. |
| 400 | Parâmetros em falta: session_id, phone, file ou type. |
| 401 | Token inválido ou expirado. Re-autentique via POST /auth/login. |
| 403 | WAF bloqueou o request multipart. Adicione o header Referer. |
| 413 | Ficheiro maior que 15 MB. |
| 415 | Tipo de ficheiro não suportado. |
| 502 | Erro no Go WhatsApp API: sessão desligada, URL inacessível ou timeout. |
Tipos de ficheiro suportados
| Categoria | MIME Types aceites | Limite WhatsApp |
|---|---|---|
| Imagem | image/jpeg, image/png, image/gif, image/webp | ~16 MB |
| Vídeo | video/mp4, video/mpeg, video/quicktime, video/webm | ~100 MB |
| Áudio | audio/mpeg, audio/ogg, audio/wav, audio/aac | ~16 MB |
| Documento | application/msword, application/vnd.openxmlformats-officedocument.*, application/vnd.ms-excel | ~100 MB |
application/pdf | ~100 MB |
O tipo é detectado pelos bytes mágicos do ficheiro — a extensão e o campo Content-Type enviados pelo cliente são ignorados na detecção. Upload PHP: máx. 15 MB.
100 pedidos por minuto por token de autenticação. Exceder este limite resulta em 429 Too Many Requests.
O erro 502 com mensagem session not connected significa que a sessão WhatsApp está desligada. Reconecte no painel em Sessões.
URLs com localhost, 127.0.0.1, 192.168.x.x ou 10.x.x.x são rejeitadas — o servidor tenta descarregar o ficheiro externamente antes de enviar ao WhatsApp.
Para enviar áudio como mensagem de voz (bolha play inline), defina ptt: true. Sem esse campo, o áudio é enviado como ficheiro de áudio normal.
session_id).| Campo | Tipo | Descrição |
|---|---|---|
session_idobrigatório |
string | UUID da sessão WhatsApp activa (ex: 17c6074e-3359-4a73-a513-a35953a007f2). |
phoneobrigatório |
string | Número com código de país, sem + (ex: 258845888195). |
typeobrigatório |
string | Deve ser text. |
messageobrigatório |
string | Conteúdo da mensagem de texto. |
message_id e log_id.session_id, phone, message).curl -X POST "https://api.mozesms.com/whatsapp/send" -H "Authorization: Bearer eyJhbGci..." -H "Content-Type: application/json" -d '{ "session_id": "17c6074e-3359-4a73-a513-a35953a007f2", "phone": "258845888195", "type": "text", "message": "Olá! Esta é uma mensagem de teste." }'
$ch = curl_init('https://api.mozesms.com/whatsapp/send'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer eyJhbGci...', 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'session_id' => '17c6074e-3359-4a73-a513-a35953a007f2', 'phone' => '258845888195', 'type' => 'text', 'message' => 'Olá! Esta é uma mensagem de teste.', ]), ]); $res = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.post( 'https://api.mozesms.com/whatsapp/send', headers={'Authorization': 'Bearer eyJhbGci...'}, json={ 'session_id': '17c6074e-3359-4a73-a513-a35953a007f2', 'phone': '258845888195', 'type': 'text', 'message': 'Olá! Esta é uma mensagem de teste.', }, timeout=30, ) print(res.json()['message_id'])
{
"success": true,
"message_id": "3EB0C767D9A2F3A4B5C6",
"log_id": 1234
}
{
"success": false,
"error": "session not connected"
}
multipart/form-data. Requer o header Referer para contornar a regra WAF Comodo 211180.| Header | Tipo | Descrição |
|---|---|---|
Authorizationobrigatório |
string | Bearer {token} |
Refererobrigatório |
string | URL do seu domínio (ex: https://meudominio.com) — obrigatório para multipart. |
| Campo | Tipo | Descrição |
|---|---|---|
session_idobrigatório |
string | UUID da sessão WhatsApp activa. |
phoneobrigatório |
string | Número com código de país, sem +. |
fileobrigatório |
file | Ficheiro a enviar (imagem, vídeo, áudio, documento, PDF). Máx. 15 MB. |
captionopcional |
string | Legenda do ficheiro. |
filenameopcional |
string | Nome visível do ficheiro (para documentos/PDFs). |
pttopcional |
boolean | true para enviar áudio como mensagem de voz (PTT). |
message_id, phone e log_id.session_id, phone, file).Referer.curl -X POST "https://api.mozesms.com/whatsapp/send/upload" -H "Authorization: Bearer eyJhbGci..." -H "Referer: https://meudominio.com" -F "session_id=17c6074e-3359-4a73-a513-a35953a007f2" -F "phone=258845888195" -F "file=@/caminho/para/imagem.jpg" -F "caption=Veja esta imagem!"
$ch = curl_init('https://api.mozesms.com/whatsapp/send/upload'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer eyJhbGci...', 'Referer: https://meudominio.com', ], CURLOPT_POSTFIELDS => [ 'session_id' => '17c6074e-3359-4a73-a513-a35953a007f2', 'phone' => '258845888195', 'file' => new CURLFile('/caminho/para/imagem.jpg', 'image/jpeg', 'imagem.jpg'), 'caption' => 'Veja esta imagem!', ], ]); $res = json_decode(curl_exec($ch), true); curl_close($ch);
import requests with open('/caminho/para/imagem.jpg', 'rb') as f: res = requests.post( 'https://api.mozesms.com/whatsapp/send/upload', headers={ 'Authorization': 'Bearer eyJhbGci...', 'Referer': 'https://meudominio.com', }, files={'file': ('imagem.jpg', f, 'image/jpeg')}, data={ 'session_id': '17c6074e-3359-4a73-a513-a35953a007f2', 'phone': '258845888195', 'caption': 'Veja esta imagem!', }, timeout=60, ) print(res.json()['message_id'])
{
"success": true,
"message_id": "3EB0C767D9A2F3A4B5C6",
"phone": "258845888195",
"log_id": 1234
}
{
"success": false,
"error": "session not connected"
}
Referer.| Campo | Tipo | Descrição |
|---|---|---|
fileobrigatório |
file | Ficheiro a armazenar. Tipo detectado automaticamente por bytes mágicos. Máx. 15 MB. |
url, mime e size.file em falta.Referer.curl -X POST "https://api.mozesms.com/whatsapp/upload" -H "Authorization: Bearer eyJhbGci..." -H "Referer: https://meudominio.com" -F "file=@/caminho/para/imagem.jpg"
$ch = curl_init('https://api.mozesms.com/whatsapp/upload'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer eyJhbGci...', 'Referer: https://meudominio.com', ], CURLOPT_POSTFIELDS => [ 'file' => new CURLFile('/caminho/para/imagem.jpg', 'image/jpeg', 'imagem.jpg'), ], ]); $res = json_decode(curl_exec($ch), true); curl_close($ch); $url = $res['url']; // usar em /whatsapp/send
import requests with open('/caminho/para/imagem.jpg', 'rb') as f: res = requests.post( 'https://api.mozesms.com/whatsapp/upload', headers={ 'Authorization': 'Bearer eyJhbGci...', 'Referer': 'https://meudominio.com', }, files={'file': ('imagem.jpg', f, 'image/jpeg')}, timeout=60, ) data = res.json() print(data['url']) # usar em /whatsapp/send
{
"success": true,
"url": "https://api.mozesms.com/uploads/whatsapp/2026/04/abc123.jpg",
"mime": "image/jpeg",
"size": 204800
}
{
"success": false,
"error": "unsupported file type"
}
/whatsapp/upload.| Campo | Tipo | Descrição |
|---|---|---|
session_idobrigatório |
string | UUID da sessão WhatsApp activa. |
phoneobrigatório |
string | Número com código de país, sem +. |
typeobrigatório |
string | image · video · audio · document · pdf |
urlobrigatório |
string | URL pública, URL MozeSMS ou data:image/jpeg;base64,.... URLs privadas (localhost, redes internas) são rejeitadas. |
captionopcional |
string | Legenda para imagem, vídeo ou documento. |
filenameopcional |
string | Nome visível para document e pdf. |
pttopcional |
boolean | true para enviar áudio como mensagem de voz. |
message_id e log_id.type inválido.# Enviar imagem com URL curl -X POST "https://api.mozesms.com/whatsapp/send" \ -H "Authorization: Bearer eyJhbGci..." \ -H "Content-Type: application/json" \ -d '{ "session_id": "17c6074e-3359-4a73-a513-a35953a007f2", "phone": "258845888195", "type": "image", "url": "https://api.mozesms.com/uploads/whatsapp/2026/04/foto.jpg", "caption": "Confirmação de entrega" }'
$ch = curl_init('https://api.mozesms.com/whatsapp/send'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer eyJhbGci...', 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'session_id' => '17c6074e-3359-4a73-a513-a35953a007f2', 'phone' => '258845888195', 'type' => 'pdf', 'url' => 'https://api.mozesms.com/uploads/whatsapp/2026/04/fatura.pdf', 'filename' => 'Fatura_Abril_2026.pdf', 'caption' => 'Fatura de Abril 2026', ]), ]); $res = json_decode(curl_exec($ch), true); curl_close($ch);
const res = await fetch('https://api.mozesms.com/whatsapp/send', { method: 'POST', headers: { 'Authorization': 'Bearer eyJhbGci...', 'Content-Type' : 'application/json', }, body: JSON.stringify({ session_id: '17c6074e-3359-4a73-a513-a35953a007f2', phone: '258845888195', type: 'image', url: 'https://api.mozesms.com/uploads/whatsapp/2026/04/foto.jpg', caption: 'Confirmação de entrega', }), }); const data = await res.json();
import requests res = requests.post( 'https://api.mozesms.com/whatsapp/send', headers={'Authorization': 'Bearer eyJhbGci...'}, json={ 'session_id': '17c6074e-3359-4a73-a513-a35953a007f2', 'phone': '258845888195', 'type': 'image', 'url': 'https://api.mozesms.com/uploads/whatsapp/2026/04/foto.jpg', 'caption': 'Confirmação de entrega', }, timeout=30, ) print(res.json()['message_id'])
{
"success": true,
"message_id": "3EB0C4A1B2C3D4E5F6",
"log_id": 1234
}
{
"success": false,
"error": "failed to send image: session not connected"
}
Changelog
Histórico de atualizações da WhatsApp Business API.
Abril 2026
Lançamento inicial da WhatsApp Business API.
Suporte a mensagens simples e templates.
Consulta de estados de entrega.
Rate limiting e validações.
Em desenvolvimento
Webhooks para eventos em tempo real.
Envio em massa (bulk).
Grupos de contacto.
Relatórios avançados.
Suporte
Para suporte técnico ou dúvidas sobre a integração da WhatsApp API:
info@mozesms.com
Segunda a Sexta, 8h às 17h (GMT+2)