Pular para o conteúdo
WbizTool

API v2 (beta)

Migrar da v1 para a v2

A API v2 faz o que a v1 faz, com chaves mais seguras, um único estilo de URL, códigos de status HTTP reais e webhooks JSON assinados. Esta página relaciona cada endpoint e campo da v1 ao equivalente na v2. O que é novo na própria v2 está na visão geral.

O que muda em tudo#

  • Chaves: o client_id + api_key da v1 viram um único cabeçalho, Authorization: Bearer wbz_live_…. Crie uma chave v2 em Configurações → Chaves de API, no cartão Chaves de API v2, só com as permissões de que o app precisa. Chaves v1 não funcionam na v2, e chaves v2 não funcionam na v1.
  • Só JSON: sem campos de formulário. Os uploads de arquivo vão para POST /media (multipart) e são enviados pelo media_id.
  • Métodos e URLs: GET para ler, POST para criar, PATCH para alterar, DELETE para cancelar ou excluir, em https://wbiztool.com/api/v2.
  • Códigos de status HTTP no lugar de "status": 0 ou 1 (veja Respostas e erros).
  • Números de telefone em formato internacional com +, sem country_code.
  • Horários em ISO 8601 com deslocamento, no lugar de campos separados de data, hora e fuso horário.
  • Webhooks são endpoints que você adiciona uma vez para o espaço de trabalho, com eventos JSON assinados, no lugar de uma URL webhook em cada mensagem.

Endpoint por endpoint#

Os caminhos da v2 são relativos a https://wbiztool.com/api/v2.

Envio, campo a campo#

v1v2Observações
client_id + api_key (corpo ou Authorization: Bearer)Authorization: Bearer wbz_live_…Uma chave v2 nova; sem client_id
phone + country_codeto.phoneUm número em E.164 com +: "9876543210" com "country_code": "91" vira {"phone": "+919876543210"}. Nenhum código do país é adicionado por você
phone com um @username (Telegram)to.username@name, t.me/name ou tg: e um id, a partir de uma conta do Telegram
group_nameto.groupO nome exato do grupo
(não existe na v1)to.contact_idUm contato salvo
whatsapp_clientfromO id do número; opcional quando há um só número conectado, como antes
msg (ou message)textAté 3.000 caracteres, como antes
msg_type 0, 1, 2nenhumUma mensagem com media é uma mensagem de mídia; media.type (image ou file) quando o link não indica
img_url / file_urlmedia.urlUm link público http(s)
file (upload na mesma requisição)media.media_idEnvie o arquivo primeiro e depois mande o id quantas vezes quiser
file_namemedia.file_namePara arquivos
date + time + timezone de schedule_msg/send_atUm único horário com o deslocamento: 24/12/2026, 10:30 e Asia/Kolkata viram "2026-12-24T10:30:00+05:30"
expire_after_secondsexpires_atUm horário, não uma duração: agora mais os segundos, com o deslocamento
webhookendpoints de webhookAdicionados uma vez com POST /webhooks, para todas as mensagens do espaço de trabalho
msg_id na respostaidA própria Message volta, com o status dela

O mesmo envio na v1 e na v2:

# v1
curl -X POST https://wbiztool.com/api/v1/send_msg/ \
  -H "Authorization: Bearer YOUR_V1_KEY" \
  -H "Content-Type: application/json" \
  -d '{"whatsapp_client": 101, "msg_type": 1, "country_code": "91", "phone": "9876543210",
       "img_url": "https://example.com/offers/diwali-sale.jpg", "msg": "Our Diwali sale starts today",
       "expire_after_seconds": 3600}'

# v2
curl -X POST https://wbiztool.com/api/v2/messages \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: diwali-9876543210" \
  -d '{"from": 101, "to": {"phone": "+919876543210"},
       "media": {"url": "https://example.com/offers/diwali-sale.jpg"}, "text": "Our Diwali sale starts today",
       "expires_at": "2026-10-20T11:30:00+05:30"}'

Alguns comportamentos da v1 deixaram de existir de propósito:

  • Nada de adivinhar o código do país. A v1 colocava country_code na frente de um número (com 91, sempre na frente de um número de 10 dígitos). A v2 usa o número exatamente como escrito, com +.
  • Nenhum download de arquivo na chamada. A v1 baixava img_url e file_url durante a requisição. A v2 verifica se o link é público e baixa o arquivo quando a mensagem é enviada; um link ruim aparece como uma mensagem failed.
  • Nenhuma linha com falha na recusa. Quando a v1 recusa um envio acima das 1.000 diárias, ela ainda salva a mensagem como falha. A v2 não salva nada quando recusa um envio.
  • Campos desconhecidos são recusados em vez de ignorados.

Status#

Os números e as palavras da v1 viram um único campo status:

v1status na v2
0 Created / Pendingqueued, ou scheduled enquanto o send_at dela ainda não chegou
1 Sentsent, delivered ou read (os tiques do WhatsApp)
2 Failedfailed
3 Cancelledcancelled
4 Expiredexpired

Os eventos de webhook são message.sent, message.failed, message.cancelled e message.expired, correspondentes a SENT, FAILED, CANCELLED e EXPIRED da v1.

Respostas e erros#

A v1 responde a muitos erros com HTTP 200 ou 400 e "status": 0, e ao sucesso com "status": 1. A v2 usa o código de status HTTP:

  • Sucesso é 200, 201 (criado) ou 202 (na fila), e o corpo é o próprio objeto, como a Message. Não há o invólucro status: 1.
  • Erros são 4xx ou 5xx com um único formato: {"error": {"code", "message", "field", "docs", "request_id"}}. Decida pelo code, não pela message em inglês. Todos os códigos estão na página de erros.
# v1
result = response.json()
if result.get("status") == 1:
    msg_id = result["msg_id"]

# v2
if response.status_code == 202:
    message_id = response.json()["id"]
else:
    error = response.json()["error"]
    if error["code"] == "number_daily_cap_reached":
        ...  # try again tomorrow

Algumas mensagens da v1 e os códigos na v2:

Mensagem da v1Código da v2
Auth Error: invalid api key401 invalid_api_key, api_key_revoked ou api_key_expired
Invalid phone number / Invalid Contact Number "…"422 invalid_phone
Msg cant be null400 text_required
Message length is too long400 text_too_long
Invalid whatsapp client422 number_not_found
Invalid whatsapp client id.422 from_required
Not enough credits402 no_credits
Daily limit reached: …429 number_daily_cap_reached
Demo Account can not access apis403 demo_account
Account Disabled403 account_disabled
Invalid JSON format: …400 invalid_json

Webhooks#

Na v1, cada mensagem pode levar uma URL webhook que recebe um msg_id=…&status=SENT codificado como formulário. Na v2:

  1. Adicione um endpoint uma vez com POST /webhooks e guarde o secret dele.
  2. Ele recebe eventos JSON de todas as mensagens do espaço de trabalho, com a Message inteira em data.message. Associe-os aos seus registros por data.message.id.
  3. Verifique a assinatura: o mesmo esquema da v1 (WbizTool-Timestamp, WbizTool-Signature: v1=…), mas com o segredo próprio do endpoint em vez do segredo do espaço de trabalho.
  4. Descarte repetidos com WbizTool-Event-Id. As novas tentativas continuam por cerca de 23 horas, não 4 tentativas em poucos minutos como na v1, e respostas 4xx também são tentadas de novo.

Os eventos de conexão da v1 (webhook_url em whatsapp/connect/) ainda não têm evento na v2: consulte GET /numbers/{id} periodicamente.

Uma checklist#

  1. Crie uma chave v2 por app

    Em Configurações → Chaves de API, só com as permissões de que ele precisa. Teste primeiro com uma chave de teste, que verifica tudo e não envia nada.

  2. Altere as requisições

    URLs e métodos novos, corpos JSON, to / from / text / media, números de telefone com +, horários com deslocamento. Adicione uma Idempotency-Key a cada envio.

  3. Altere o tratamento de erros

    Confira o status HTTP e depois error.code. Trate 429 esperando o Retry-After.

  4. Migre os webhooks

    Adicione um endpoint, verifique as assinaturas com o segredo dele e descarte repetidos pelo id do evento.

  5. Troque e revogue

    Quando o app estiver rodando na v2, exclua a chave v1 dele em Configurações → Chaves de API.

Relacionados#