Genuka WA docs

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 GraphNom donné par MetaCe qu'il indique
463ExpiredLe jeton a expiré, a été révoqué ou n'est plus valide
467Invalid Access TokenLe jeton a expiré, a été révoqué ou n'est plus valide
460Password ChangedLa personne qui a généré le jeton a changé de mot de passe
458App Not InstalledL'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 :

409 — POST /api/v1/messages
{
  "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 :

  1. Ne réessayez pas en boucle. retryable: false : le même appel échouera de la même façon.
  2. Écrivez au support Genuka avec l'en-tête x-request-id de la réponse et meta.traceId.
  3. Ne demandez pas tout de suite au client de se reconnecter. Vérifiez d'abord GET /api/v1/connections. disconnected signifie 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énement account_update relayé à vos webhooks dit lequel de ces cas s'applique. S'il est toujours connected, 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_update signale PARTNER_APP_UNINSTALLED quand un client désautorise ou désinstalle votre app, et PARTNER_REMOVED quand un compte n'est plus partagé avec vous (Meta, webhook account_update). Genuka WA relaie ces événements sur vos webhooks (événement account_update), mais des deux, seul PARTNER_REMOVED fait passer le numéro en disconnected : après un PARTNER_APP_UNINSTALLED, il reste connected.
  • 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.

Sources

Sur cette page