Erreur WhatsApp 190 : jeton d'accès expiré, solution
Erreur WhatsApp 190 (access token expired) : quel jeton a expiré, comment le remplacer durablement, et pourquoi Genuka WA vous en dispense.
L'erreur WhatsApp 190 signifie que le jeton d'accès envoyé à la Cloud API de Meta a expiré ou n'est plus valide. La correction consiste à obtenir un nouveau jeton, et surtout à cesser d'utiliser un jeton utilisateur temporaire : un jeton d'utilisateur système ne tombe pas en quelques heures. Avec Genuka WA, vous ne manipulez aucun jeton Meta.
Que signifie l'erreur 190 ?
Meta la classe parmi les erreurs d'autorisation de la Cloud API :
« Your access token has expired. » — solution proposée : « Get a new access token. » — Meta, codes d'erreur de la Cloud API
La documentation générale de Graph, sur laquelle la Cloud API est construite, nomme le même code « Access token has expired » et détaille des sous-codes (Meta, Graph API, gestion des erreurs) :
| Sous-code Graph | Nom donné par Meta | Ce qu'il indique |
|---|---|---|
463 | Expired | Le jeton a expiré, a été révoqué ou n'est plus valide |
467 | Invalid Access Token | Le jeton a expiré, a été révoqué ou n'est plus valide |
460 | Password Changed | La personne qui a généré le jeton a changé de mot de passe |
458 | App Not Installed | L'utilisateur ne s'est pas connecté à votre application |
Ne bâtissez pas votre logique sur ces sous-codes : la page d'erreurs WhatsApp indique que
error_subcode est déprécié et n'est plus renvoyé à partir de la version 16.0 de Graph. Le code
190 et le champ details suffisent.
Quand l'erreur 190 apparaît-elle ?
- Vous utilisez le jeton de la page API Setup. Le tableau de bord d'app Meta génère un jeton utilisateur à chaque visite de WhatsApp > API Setup. Meta le réserve aux premiers tests : ces jetons « expirent vite », il faut en générer un nouveau toutes les quelques heures (Meta, Access tokens). C'est la cause la plus fréquente d'un service qui marche le matin et échoue l'après-midi.
- Le jeton a été invalidé. Mot de passe changé, application retirée par l'utilisateur, jeton révoqué : Meta répond 190 même avant la date d'expiration.
- Vous êtes partenaire et le jeton d'un client est mort. Un Tech Provider reçoit, à la fin de l'Embedded Signup, un jeton d'utilisateur système d'intégration propre à ce client. Nous avons constaté qu'il cesse de fonctionner dès que le client modifie l'accès du partenaire dans son Business Manager : Meta répond alors 190 « Authentication Error » à chaque envoi, sur un numéro par ailleurs en bonne santé.
Comment corriger l'erreur 190 ?
Si vous appelez la Cloud API avec votre propre jeton
Inspectez le jeton. Collez-le dans le
débogueur de jetons de Meta : il
affiche la date d'expiration et les permissions. Il doit porter whatsapp_business_management et
whatsapp_business_messaging
(Meta, support WhatsApp).
Remplacez un jeton utilisateur par un jeton d'utilisateur système. Dans les paramètres
d'entreprise, section System Users : créez un utilisateur système, donnez-lui le contrôle de
votre app, puis Generate token en choisissant l'app, une préférence d'expiration et les
permissions business_management, whatsapp_business_management et
whatsapp_business_messaging
(Meta, Access tokens).
Donnez-lui accès aux comptes. Un utilisateur système sans accès au compte WhatsApp visé ne déclenche plus 190 mais 200 : assignez-lui le compte WhatsApp et le compte de messagerie dans Meta Business Suite, onglet People de chaque compte (même page).
Stockez-le comme un secret opaque. Meta prévient que le format des jetons peut changer : pas de longueur fixe en base, pas de décodage.
Si vous passez par Genuka WA
Vous n'avez rien à régénérer. Genuka WA détient les accès à la Cloud API : chaque appel sur votre numéro part avec le jeton d'utilisateur système de Genuka, créé sans date d'expiration, et non avec le jeton remis par l'Embedded Signup au moment de la connexion. C'est justement pour éviter le cas décrit plus haut que Genuka a fait ce choix.
Un 190 dans une réponse Genuka WA est donc, dans la grande majorité des cas, un incident côté
Genuka. Il revient ainsi :
{
"error": "send_config",
"message": "Authentication Error",
"meta": {
"errorClass": "config",
"retryable": false,
"code": 190,
"traceId": "AbC…"
}
}Sur la création d'un template, le même refus revient en 403 meta_rejected, avec le même objet
meta (référence API). Dans les deux cas :
- Ne réessayez pas en boucle.
retryable: false: le même appel échouera de la même façon. - Écrivez au support Genuka avec l'en-tête
x-request-idde la réponse etmeta.traceId. - Ne demandez pas tout de suite au client de se reconnecter. Vérifiez d'abord
GET /api/v1/connections.disconnectedsignifie que Meta a signalé le compte comme n'étant plus partagé avec Genuka, ou supprimé, ou que vous avez libéré le numéro vous-même. Un client qui a retiré l'accès le rétablit par le lien de connexion, sans nouvelle place ; un numéro libéré demande de nouveau une place libre ; un compte supprimé ou désactivé par Meta (erreur 368) ne se rétablit pas ainsi, et l'événementaccount_updaterelayé à vos webhooks dit lequel de ces cas s'applique. S'il est toujoursconnected, restez-en au support Genuka.
Ne confondez pas avec les erreurs de votre propre clé API, qui ne viennent jamais de Meta :
401 missing_bearer_token (en-tête absent) et 401 invalid_token (clé inconnue ou révoquée), voir
Authentification.
const response = await fetch("https://wa.genuka.com/api/v1/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GENUKA_WA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
connectionId: "con_1",
to: "+237690000001",
template: { name: "confirmation_commande", language: "fr", variables: ["Awa", "CMD-1042"] },
}),
});
const json = await response.json();
if (response.status === 401) {
// Votre clé Genuka : absente, inconnue ou révoquée. Rien à voir avec Meta.
throw new Error(`Clé API refusée : ${json.error}`);
}
if (json.meta?.code === 190 || json.meta?.code === 0) {
// Jeton Meta refusé : côté Genuka. On s'arrête et on alerte, sans réessayer.
console.error("Jeton Meta refusé", {
requestId: response.headers.get("x-request-id"),
traceId: json.meta.traceId,
});
}Comment éviter l'erreur 190 ?
- Jamais de jeton API Setup en production. Il est fait pour envoyer un premier message de test, pas pour un service qui tourne la nuit.
- Un jeton d'utilisateur système par environnement, avec seulement les permissions WhatsApp utiles, stocké dans votre gestionnaire de secrets.
- Surveillez les retraits d'accès. Si vous êtes partenaire, le webhook
account_updatesignalePARTNER_APP_UNINSTALLEDquand un client désautorise ou désinstalle votre app, etPARTNER_REMOVEDquand un compte n'est plus partagé avec vous (Meta, webhook account_update). Genuka WA relaie ces événements sur vos webhooks (événementaccount_update), mais des deux, seulPARTNER_REMOVEDfait passer le numéro endisconnected: après unPARTNER_APP_UNINSTALLED, il resteconnected. - Alertez sur la classe, pas sur le texte. Chez Genuka WA,
meta.errorClass: "config"regroupe jeton, permission et enregistrement : un humain doit regarder, aucun réessai ne réglera rien.
Quels codes sont liés ?
- 0 : Meta n'a pas pu authentifier l'utilisateur de l'app, même remède.
- 200 : le jeton est valide mais n'a pas accès au compte ou à la permission.
- 10 : permission non accordée ou retirée.
- 3 : capacité ou permission manquante pour cet endpoint.
FAQ
Quelle est la durée de vie d'un jeton WhatsApp Cloud API ?
Elle dépend du type. Un jeton utilisateur, comme celui de la page API Setup, expire en quelques heures. Un jeton d'utilisateur système est durable, et vous choisissez sa préférence d'expiration au moment de le générer.
Faut-il réessayer un envoi refusé en 190 ?
Pas avant d'avoir changé de jeton. Le même jeton produira la même erreur : réessayer ne fait que retarder l'alerte.
Mon client doit-il se reconnecter après une erreur 190 sur Genuka WA ?
Seulement si son numéro apparaît disconnected dans GET /api/v1/connections parce qu'il a
retiré l'accès de Genuka : l'événement account_update relayé à vos webhooks le confirme. Un
compte supprimé ou désactivé par Meta ne se rétablit pas par une reconnexion. Si le numéro est
toujours connected, écrivez au support Genuka avec x-request-id et meta.traceId.
Dois-je régénérer ma clé API Genuka ?
Non. Votre clé pk_live_… authentifie vos appels auprès de Genuka WA, pas auprès de Meta. Une clé
refusée produit un 401 de Genuka, jamais un 190.