Todas as rotas ficam em /v1/phone_numbers/{id}/…, onde {id} é o UUID interno ou o phone_number_id da Meta (veja GET /v1/phone_numbers). Leitura exige numbers:read; escrita, numbers:write. Os dados vêm e vão direto para a Meta, a cada chamada: o BotoZap não guarda cópia. Nenhuma rota aceita chave sandbox.
Recusas comuns a todas: 404 not_found (número de outra Conta), 409 sandbox_not_supported, 409 connection_inactive (reconecte em Canais), 409 reconnect_required (autorização da Meta vencida), 429 meta_rate_limited, 403 meta_permission_denied e 502 meta_error. Escrita que a Meta não confirmou a tempo responde 504 meta_unconfirmed: consulte antes de repetir. A resposta nunca traz a mensagem crua da Meta.
Perfil
GET /profile devolve about, description, address, email, websites, vertical, profile_picture_url e editable. PATCH /profile muda só os campos enviados (string vazia limpa; about precisa de 1 a 139 caracteres) e devolve o perfil relido na Meta. Limites: description 512, address 256, email 128, até 2 websites com http(s)://. vertical aceita os valores do enum da Meta (RETAIL, RESTAURANT, BEAUTY, HEALTH, PROF_SERVICES, OTHER…).
curl -X PATCH https://botozap.com.br/api/v1/phone_numbers/$PHONE_ID/profile \
-H "Authorization: Bearer $BOTOZAP_KEY" \
-H "Content-Type: application/json" \
-d '{
"about": "Atendemos de segunda a sábado",
"email": "contato@seunegocio.com.br",
"websites": ["https://seunegocio.com.br"],
"vertical": "RETAIL"
}'A foto vai por multipart/form-data, no campo file (JPG ou PNG, até 4 MB):
curl -X POST https://botozap.com.br/api/v1/phone_numbers/$PHONE_ID/profile/photo \
-H "Authorization: Bearer $BOTOZAP_KEY" \
-F "file=@logo.png;type=image/png"Coexistência. Número que também está no app WhatsApp Business do celular tem editable: false, e o PATCH e a foto respondem 409 coexistence_not_supported: a Meta não aceita mudar o perfil pela API nesse modo. O perfil é editado no app.
No acesso por OAuth (ChatGPT e outros apps conectados), mudar o perfil e a foto fica só no painel e na chave de API: e-mail, site e foto são o contato público do negócio.
Perguntas prontas e comandos
prompts são as perguntas prontas (ice breakers): até 4, com até 80 caracteres, sem emoji. Aparecem para quem abre a conversa pela primeira vez. commands são os comandos que a pessoa vê ao digitar /: até 30, command_name até 32 caracteres sem espaço e command_description até 256. Tocar numa pergunta ou mandar um comando chega como mensagem de texto comum, no webhook whatsapp.message.received.
PATCH mantém o campo omitido e remove com lista vazia; DELETE remove tudo. Gravar perguntas ou comandos é automação: no plano sem automações responde 403 plan_restricted (remover segue liberado).
curl -X PATCH https://botozap.com.br/api/v1/phone_numbers/$PHONE_ID/conversational-automation \
-H "Authorization: Bearer $BOTOZAP_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompts": ["Ver horários", "Fazer um pedido"],
"commands": [{ "command_name": "cardapio", "command_description": "Receber o cardápio do dia" }]
}'A Meta ainda lista enable_welcome_message na referência, mas o guia atual não descreve mais a mensagem de boas-vindas nem o evento que ela gerava. Por isso a API do BotoZap não oferece essa opção.
QR codes e link curto
Cada QR code abre a conversa com o número e a mensagem pronta já escrita (até 140 caracteres), e tem um link curto wa.me/message/… (deep_link_url). A Meta aceita até 2.000 por número e não mede escaneamentos.
curl -X POST https://botozap.com.br/api/v1/phone_numbers/$PHONE_ID/qr-codes \
-H "Authorization: Bearer $BOTOZAP_KEY" \
-H "Content-Type: application/json" \
-d '{ "prefilled_message": "Oi! Vi o cartaz na loja.", "image_format": "SVG" }'{
"data": {
"code": "4O4YGZEG3RIVE1",
"prefilled_message": "Oi! Vi o cartaz na loja.",
"deep_link_url": "https://wa.me/message/4O4YGZEG3RIVE1",
"qr_image_url": "https://scontent.xx.fbcdn.net/..."
}
}POST não é idempotente: diante de 504 meta_unconfirmed, liste com GET /qr-codes antes de criar de novo. GET /qr-codes/{code}?image_format=PNG|SVG traz qr_image_url, um link temporário do CDN da Meta: baixe na hora. PATCH /qr-codes/{code} troca só a mensagem; o código e a imagem continuam os mesmos. DELETE responde 204 e não tem volta: quem escanear passa a ver "expirado". No OAuth, apagar exige Administrador.
Contatos bloqueados
Contato bloqueado não manda mensagem nem liga para o número, e o número não envia nada para ele (o envio recusa). A Meta só bloqueia quem mandou mensagem nas últimas 24 horas: fora disso, 422 block_window_closed. Outros: 422 cannot_block_self e 409 blocklist_full (64 mil por número).
POST /blocked-users aceita contact_id (contato da Conta neste número) ou user (telefone com DDI). GET /blocked-users lista 100 por página (after para a próxima), com contact_id e name quando o wa_id é de um contato seu. DELETE /blocked-users/{wa_id} desbloqueia.
curl -X POST https://botozap.com.br/api/v1/phone_numbers/$PHONE_ID/blocked-users \
-H "Authorization: Bearer $BOTOZAP_KEY" \
-H "Content-Type: application/json" \
-d '{ "contact_id": "6f0c…" }'Todas as rotas, com escopo, estão na referência. Para quem opera pelo painel, a Central de Ajuda explica a tela.
