Integração
API de WhatsApp para Python
Use requests ou httpx para integrar WhatsApp em Python.
import requests
response = requests.post(
"https://zapixo.com.br/api/v1/messages/text",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"instance": "python-app",
"number": "5511999999999",
"text": "Olá do Python!",
},
)
print(response.json())Em Python, a integração com o Zapixo é requests ou httpx para enviar e uma rota FastAPI ou Flask para receber. A API é REST com JSON, sem SDK para instalar.
Para o primeiro envio com calma, o tutorial de Python no blog cobre texto, mídia e estrutura de projeto. Aqui o foco é a integração inteira, com recebimento e os erros de produção.
O que dá para fazer com Python e WhatsApp
Rotina agendada
Um script no cron avisa os clientes de manhã: vencimento, agenda do dia, pedido pronto para retirar.
Atendimento com dados do sistema
A rota do Django ou do FastAPI recebe a pergunta e responde com o dado real do banco.
Bot com modelo de linguagem
O webhook passa o texto para o modelo, que devolve a resposta enviada pelo mesmo número.
Registro para análise
Toda mensagem recebida vai para o banco, pronta para relatório de volume e tempo de resposta.
Enviar mensagens pelo Python
Guarde a chave no ambiente
Gere a chave no painel e coloque em
ZAPIXO_API_KEY. Ela começa comzpx_e dá acesso para enviar em nome da instância, então fica fora do código.Função de envio com requests
Uma
Sessionreaproveita a conexão e o header. Otimeoutnão é opcional: sem ele, o requests espera para sempre uma conexão travada.import os import re import requests BASE = "https://zapixo.com.br/api/v1" SESSION = requests.Session() SESSION.headers["Authorization"] = f"Bearer {os.environ['ZAPIXO_API_KEY']}" def enviar_texto(instance: str, number: str, text: str) -> dict: resp = SESSION.post( f"{BASE}/messages/text", json={"instance": instance, "number": re.sub(r"\D", "", number), "text": text}, timeout=15, ) if resp.status_code == 429: reabre = resp.headers.get("X-RateLimit-Reset") raise RuntimeError(f"limite por minuto atingido, reabre em {reabre}") resp.raise_for_status() return resp.json()Assíncrono com httpx
Em código async, o
httpxfaz o mesmo sem bloquear:import httpx async with httpx.AsyncClient( base_url=BASE, headers={"Authorization": f"Bearer {os.environ['ZAPIXO_API_KEY']}"}, timeout=15, ) as client: resp = await client.post( "/messages/text", json={"instance": "minha-loja", "number": "5511999999999", "text": "Olá!"}, ) resp.raise_for_status()
Receber mensagens no Python
Cadastre a URL no painel
Abra a instância no painel e cole a URL da sua rota em Webhook de mensagens. Precisa ser HTTPS. O Zapixo não assina as requisições, então ponha um segredo na URL e confira na rota:
https://seuapp.com/webhooks/zapixo?chave=....A rota em FastAPI
BackgroundTasksroda o processamento depois da resposta. O evento de mensagem nova émessages.upsert:import os from fastapi import BackgroundTasks, FastAPI, HTTPException, Request app = FastAPI() @app.post("/webhooks/zapixo") async def webhook(request: Request, tasks: BackgroundTasks, chave: str = ""): if chave != os.environ["ZAPIXO_WEBHOOK_SECRET"]: raise HTTPException(status_code=401) payload = await request.json() data = payload.get("data") or {} key = data.get("key") or {} if payload.get("event") == "messages.upsert" and not key.get("fromMe"): tasks.add_task(processar, data) return {"ok": True}A rota em Flask
No Flask, responda logo e mande o trabalho para fora da requisição — uma fila como Celery ou RQ:
@app.post("/webhooks/zapixo") def webhook(): if request.args.get("chave") != os.environ["ZAPIXO_WEBHOOK_SECRET"]: abort(401) payload = request.get_json(silent=True) or {} data = payload.get("data") or {} if payload.get("event") == "messages.upsert" and not data.get("key", {}).get("fromMe"): processar.delay(data) # tarefa Celery return {"ok": True}Número e texto
O número vem no
remoteJid, com sufixo. Texto simples fica emconversation; resposta citando outra mensagem costuma vir emextendedTextMessage:numero = data["key"]["remoteJid"].split("@")[0] msg = data.get("message") or {} texto = msg.get("conversation") or (msg.get("extendedTextMessage") or {}).get("text", "")
Erros comuns e como resolver
- Mensagem processada duas vezes
- Se a rota não devolver 2xx em até 10 segundos, o Zapixo tenta de novo — até 3 tentativas. Responda rápido e guarde
data['key']['id']das mensagens já tratadas. - O bot responde a si mesmo
- Mensagens enviadas pela própria instância também chegam, com
fromMe: true. Filtre antes de responder, senão o bot conversa com ele mesmo. - Mensagem de grupo
- Grupo chega com
remoteJidterminando em@g.us. Se a rota só atende conversa individual, descarte. - Erro 429
- 60 requisições por minuto por chave. No
429, espere até o horário deX-RateLimit-Reset(segundos Unix). Para lista grande, espace os envios em vez de disparar em laço. - CSRF no Django
- A view do webhook recebe POST de fora do site, sem token CSRF. Marque-a com
@csrf_exempte proteja pelo segredo na URL. - Erros 401, 404 e 502
401: chave errada ou sem oBearerna frente.404:instancenão bate com o nome no painel.502: a entrega ao WhatsApp falhou, e o motivo vem emdetails.
Perguntas frequentes
Existe SDK do Zapixo para Python?
Não precisa. A API é REST com JSON, e requests ou httpx resolvem.
Funciona com Django?
Funciona. A lógica do webhook é a mesma, numa view marcada com @csrf_exempt.
O webhook do Zapixo tem assinatura?
Não. Proteja a rota com um segredo na URL e confira em cada requisição.
Consigo enviar imagem pelo Python?
Sim, pelo endpoint /api/v1/messages/media, com mediaUrl (link público do arquivo) e caption opcional.
O trial tem limite de mensagens?
Tem. Ao atingir o limite, a API responde 402 com o link para assinar.
Leia também
- Como enviar mensagem WhatsApp com Python
Guia prático para integrar Python com a API REST do Zapixo e enviar mensagens de texto e mídia no WhatsApp de forma programática.