Erreurs et idempotence
Raisonnez sur le code d'erreur, pas sur le statut. Et sécurisez chaque nouvelle tentative qui coûte de l'argent.
Raisonnez sur le code, pas sur le statut
Les erreurs sont renvoyées sous la forme { "error": "<code>" }. Le statut seul ne
suffit pas pour décider quoi faire : deux 403 peuvent exiger des corrections
opposées.
| Statut | Code | Ce que cela signifie, et que faire |
|---|---|---|
| 401 | invalid_key | Clé inconnue ou révoquée. Créez-en une nouvelle ; réessayer n'aidera jamais. |
| 403 | ip_not_allowed | La clé a une liste d'adresses IP autorisées et cette adresse n'y figure pas. La clé est valide — ajoutez l'adresse sur developers.wasync.app/keys. Ne la renouvelez pas. |
| 403 | insufficient_scope | Le jeton n'a pas le scope requis par ce endpoint. |
| 403 | forbidden_portal_kind | POST /connections sur un portail Bitrix24. Les connexions y sont créées par l'administrateur du portail. |
| 400 | invalid_phone_number | phoneNumber doit contenir uniquement des chiffres, sans + initial. |
| 400 | invalid_webhook | L'URL doit être en HTTPS sur un hôte accessible publiquement. |
| 402 | — | La licence de la connexion a expiré. Voir Licences et essai. |
| 409 | already_connected | La session est active ; il n'y a rien à associer. |
| 409 | not_supported_for_provider | Une opération réservée aux qr sur un numéro cloud_api. Définitif — ne réessayez pas. |
| 422 | recipient_not_on_whatsapp | WhatsApp n'a trouvé aucun compte pour le destinataire. Vérifiez que le numéro est au format international (indicatif du pays en premier, sans zéro initial) et que la personne utilise WhatsApp. Définitif pour ce numéro — ne réessayez pas à l'identique. |
| 502 | send_failed | WhatsApp n'a pas pu remettre le message pour une raison étrangère au destinataire (session ou fournisseur). Réessayez après un court délai ; si le problème persiste, vérifiez l'état de la connexion. |
| 429 | warmup_limited | Plafond horaire de montée en charge sur un nouveau numéro qr. Patientez quelques minutes. |
| 429 | rate_limited | Limiteur anti-abus. Respectez Retry-After s'il est présent ; gardez de toute façon un délai d'attente par défaut. |
| 502 | pairing_code_unavailable | Un résultat ordinaire, pas une panne — repassez au QR. |
Retry-After n'est pas garanti sur chaque 409/429 : ne faites donc jamais
dépendre votre délai d'attente de cet en-tête.
Idempotence sur POST /connections
Créer une connexion provisionne une session WhatsApp et consomme un emplacement
payant. Sans protection, un client qui dépasse le délai et réessaie créerait une
seconde connexion — et vous paieriez sans le savoir deux emplacements pour un
seul client. L'en-tête facultatif Idempotency-Key supprime ce risque. Il est
pris en charge sur POST /connections uniquement ; sans lui, le
comportement reste exactement le même qu'avant.
Une clé est une chaîne opaque quelconque de 255 caractères maximum, propre à votre espace de travail (deux partenaires qui utilisent la même chaîne ne entrent jamais en collision), et elle reste valide 24 heures à partir de la première requête qui l'a utilisée.
201 Created.200 OK ainsi que l'en-tête de réponse Idempotency-Replayed: true. Le qr de cette réponse est récupéré à nouveau, ce n'est pas le code stocké à la première création : les codes d'appairage changent environ toutes les 20 secondes, et un QR périmé renvoyé tel quel ne pourrait tout simplement pas être scanné. Considérez le 200 comme un succès, pas comme une erreur.400 { "error": "idempotency_key_reuse" }. La comparaison porte sur un hachage du corps canonique ; l'ordre des clés JSON n'a donc pas d'importance.409 { "error": "idempotency_in_progress" } avec Retry-After: 1. Respectez-le et réessayez avec la même clé.Une clé de plus de 255 caractères est rejetée avec
400 { "error": "idempotency_key_invalid" } — jamais tronquée. Un en-tête vide
ou composé uniquement d'espaces est considéré comme absent. La forme du corps de
la réponse reste inchangée dans tous les cas.
Générez une clé par tentative d'intégration d'un client
Un nouvel UUID (crypto.randomUUID()) créé juste avant l'appel et réutilisé
uniquement par les nouvelles tentatives de cet appel. N'utilisez pas une clé
par processus, par API key, par jour, ni une constante. Avec une clé aussi
large, le deuxième client que vous intégrez reçoit la connexion du premier au
lieu de la sienne.
Idempotence sur les envois
POST /messages accepte un idempotencyKey dans le corps (et non dans un
en-tête). Envoyez-en toujours un — un UUID par envoi logique.
- En cas d'erreur ou de dépassement de délai, réessayez avec la même clé. Une nouvelle clé produit un second vrai message WhatsApp sur le téléphone de quelqu'un.
- Sur
409 in_progress, interrogez de nouveau avec la même clé : respectezRetry-Afters'il est présent, sinon patientez environ 5 s. - Un envoi lent n'est pas un envoi échoué. Réglez le délai d'attente HTTP à 180 s au minimum.