Configurações do número do WhatsApp

As mesmas configurações da tela Canais › Configurar, pela API.

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.