Aller au contenu
WbizTool

API v2 (bêta)

Passer de la v1 à la v2

L'API v2 fait tout ce que fait la v1, avec des clés plus sûres, un seul style d'URL, de vrais codes de statut HTTP et des webhooks JSON signés. Cette page fait correspondre chaque endpoint et champ v1 à son équivalent v2. Les nouveautés propres à la v2 sont décrites dans la présentation.

Ce qui change partout#

  • Clés : le client_id + api_key de la v1 deviennent un seul en-tête, Authorization: Bearer wbz_live_…. Créez une clé v2 sur Paramètres → Clés API, dans la carte Clés API v2, avec uniquement les scopes dont l'application a besoin. Les clés v1 ne fonctionnent pas sur la v2, et les clés v2 ne fonctionnent pas sur la v1.
  • Uniquement du JSON : pas de champs de formulaire. Les téléversements de fichiers passent par POST /media (multipart) et sont envoyés par media_id.
  • Méthodes et URL : GET pour lire, POST pour créer, PATCH pour modifier, DELETE pour annuler ou supprimer, sous https://wbiztool.com/api/v2.
  • Des codes de statut HTTP au lieu de "status": 0 ou 1 (voir Réponses et erreurs).
  • Les numéros de téléphone au format international avec +, sans country_code.
  • Les heures au format ISO 8601 avec un décalage, au lieu de champs séparés pour la date, l'heure et le fuseau horaire.
  • Les webhooks sont des endpoints que vous ajoutez une fois pour l'espace de travail, avec des événements JSON signés, au lieu d'une URL webhook sur chaque message.

Endpoint par endpoint#

Les chemins v2 sont relatifs à https://wbiztool.com/api/v2.

L'envoi, champ par champ#

v1v2Remarques
client_id + api_key (corps ou Authorization: Bearer)Authorization: Bearer wbz_live_…Une nouvelle clé v2 ; pas de client_id
phone + country_codeto.phoneUn seul numéro au format E.164 avec + : "9876543210" avec "country_code": "91" devient {"phone": "+919876543210"}. Aucun indicatif de pays n'est ajouté à votre place
phone avec un @username (Telegram)to.username@name, t.me/name ou tg: suivi d'un identifiant, depuis un compte Telegram
group_nameto.groupLe nom exact du groupe
(absent de la v1)to.contact_idUn contact enregistré
whatsapp_clientfromL'id du numéro ; facultatif lorsqu'un seul numéro est connecté, comme avant
msg (ou message)textJusqu'à 3 000 caractères, comme avant
msg_type 0, 1, 2aucunUn message avec media est un message média ; media.type (image ou file) lorsque le lien ne l'indique pas
img_url / file_urlmedia.urlUn lien http(s) public
file (téléversement dans la même requête)media.media_idTéléversez d'abord, puis envoyez l'identifiant aussi souvent que vous le souhaitez
file_namemedia.file_namePour les fichiers
date + time + timezone de schedule_msg/send_atUne seule heure avec son décalage : 24/12/2026, 10:30 et Asia/Kolkata deviennent "2026-12-24T10:30:00+05:30"
expire_after_secondsexpires_atUne heure, pas une durée : maintenant plus les secondes, avec son décalage
webhookendpoints de webhookAjoutés une seule fois avec POST /webhooks, pour tous les messages de l'espace de travail
msg_id dans la réponseidLe Message lui-même est renvoyé, avec son status

Le même envoi en v1 et en 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"}'

Quelques comportements de la v1 disparaissent volontairement :

  • Plus de devinette de l'indicatif du pays. La v1 ajoutait country_code devant un numéro (avec 91, toujours devant un numéro à 10 chiffres). La v2 prend le numéro exactement tel qu'il est écrit avec +.
  • Plus de téléchargement de fichier lors de l'appel. La v1 récupérait img_url et file_url pendant la requête. La v2 vérifie que le lien est public et récupère le fichier au moment de l'envoi du message ; un mauvais lien apparaît comme un message failed.
  • Plus de ligne en échec lors d'un refus. Quand la v1 refuse un envoi au-delà des 1 000 quotidiens, elle enregistre quand même le message comme échoué. La v2 n'enregistre rien lorsqu'elle refuse un envoi.
  • Les champs inconnus sont refusés au lieu d'être ignorés.

Statuts#

Les nombres et les mots de la v1 deviennent un seul champ status :

v1status v2
0 Created / Pendingqueued, ou scheduled tant que son send_at est à venir
1 Sentsent, delivered ou read (les coches WhatsApp)
2 Failedfailed
3 Cancelledcancelled
4 Expiredexpired

Les événements webhook sont message.sent, message.failed, message.cancelled et message.expired, correspondant aux SENT, FAILED, CANCELLED et EXPIRED de la v1.

Réponses et erreurs#

La v1 répond à de nombreuses erreurs avec le code HTTP 200 ou 400 et "status": 0, et au succès avec "status": 1. La v2 utilise le code de statut HTTP :

  • Le succès est 200, 201 (créé) ou 202 (mis en file d'attente), et le corps est l'objet lui-même, comme le Message. Il n'y a pas d'enveloppe status: 1.
  • Les erreurs sont des 4xx ou 5xx avec une seule forme : {"error": {"code", "message", "field", "docs", "request_id"}}. Basez-vous sur code, pas sur le message en anglais. Chaque code se trouve sur la page des erreurs.
# 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

Quelques messages v1 et leurs codes v2 :

Message v1Code 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#

En v1, chaque message peut porter une URL webhook qui reçoit un msg_id=…&status=SENT encodé comme un formulaire. En v2 :

  1. Ajoutez un endpoint une seule fois avec POST /webhooks et conservez son secret.
  2. Il reçoit des événements JSON pour tous les messages de l'espace de travail, avec le Message complet dans data.message. Rapprochez-les de vos données grâce à data.message.id.
  3. Vérifiez la signature : le même principe que pour la v1 (WbizTool-Timestamp, WbizTool-Signature: v1=…), mais avec le secret propre à l'endpoint au lieu de celui de l'espace de travail.
  4. Écartez les doublons avec WbizTool-Event-Id. Les nouvelles tentatives se poursuivent pendant environ 23 heures, et non 4 essais en quelques minutes comme en v1, et les réponses 4xx sont aussi retentées.

Les événements de connexion de la v1 (webhook_url sur whatsapp/connect/) n'ont pas encore d'événement v2 : interrogez plutôt GET /numbers/{id}.

Liste de contrôle#

  1. Créez une clé v2 par application

    Sur Paramètres → Clés API, avec uniquement les scopes dont elle a besoin. Essayez-la d'abord avec une clé de test, qui vérifie tout et n'envoie rien.

  2. Modifiez les requêtes

    Nouvelles URL et méthodes, corps JSON, to / from / text / media, numéros de téléphone avec +, heures avec décalage. Ajoutez une Idempotency-Key à chaque envoi.

  3. Modifiez la gestion des erreurs

    Vérifiez le statut HTTP, puis error.code. Gérez 429 en attendant la durée de Retry-After.

  4. Migrez les webhooks

    Ajoutez un endpoint, vérifiez les signatures avec son secret, et écartez les doublons grâce à l'identifiant de l'événement.

  5. Basculez et révoquez

    Une fois que l'application tourne sur la v2, supprimez sa clé v1 sur Paramètres → Clés API.

Voir aussi#