WhatsApp error 190: access token expired — cause and fix
WhatsApp Cloud API error 190 (access token expired): which token expired, how to replace it for good, and why Genuka WA users never handle Meta tokens.
WhatsApp error 190 means the access token sent to Meta's Cloud API has expired or is no longer valid. The fix is a new token, and above all to stop using a temporary user token: a system user token does not die after a few hours. With Genuka WA, you never handle a Meta token at all.
What does error 190 mean?
Meta lists it among the Cloud API authorization errors:
"Your access token has expired." — suggested fix: "Get a new access token." — Meta, Cloud API error codes
The general Graph API documentation, which the Cloud API is built on, names the same code "Access token has expired" and documents subcodes (Meta, Graph API error handling):
| Graph subcode | Meta's name | What it tells you |
|---|---|---|
463 | Expired | The token expired, was revoked or is otherwise invalid |
467 | Invalid Access Token | The token expired, was revoked or is otherwise invalid |
460 | Password Changed | The person who generated the token changed their password |
458 | App Not Installed | The user has not logged into your app |
Do not build logic on those subcodes: the WhatsApp error page says error_subcode is deprecated
and no longer returned from Graph v16.0 onward. The 190 code and the details field are enough.
When does error 190 happen?
- You are using the API Setup token. Meta's App Dashboard generates a fresh user token every time you open WhatsApp > API Setup. Meta meant it for first tests: user tokens "expire quickly", so you have to generate a new one every few hours (Meta, Access tokens). It is the usual reason a service works in the morning and fails in the afternoon.
- The token was invalidated. Password changed, app removed by the user, token revoked: Meta answers 190 even before the expiry date.
- You are a partner and one customer's token died. At the end of Embedded Signup, a Tech Provider receives a business integration system user token scoped to that customer. We have seen it stop working as soon as the customer edits the partner's access in their Business Manager: Meta then answers 190 "Authentication Error" on every send, for a number that is otherwise healthy.
How do I fix error 190?
If you call the Cloud API with your own token
Inspect the token. Paste it into
Meta's access token debugger: it shows
the expiry and the permissions. It needs whatsapp_business_management and
whatsapp_business_messaging
(Meta, WhatsApp support).
Replace a user token with a system user token. In Business settings, System Users: create
a system user, give it control of your app, then Generate token, picking the app, an expiration
preference and the business_management, whatsapp_business_management and
whatsapp_business_messaging permissions
(Meta, Access tokens).
Give it access to the accounts. A system user without access to the target WhatsApp account no longer gets 190 but 200: assign it the WhatsApp account and the Messaging account in Meta Business Suite, from each account's People tab (same page).
Store it as an opaque secret. Meta warns that token formats can change: no fixed column length, no decoding.
If you go through Genuka WA
There is nothing for you to regenerate. Genuka WA holds the Cloud API access: every call on your number goes out with Genuka's system user token, created with no expiry date, rather than with the token Embedded Signup returned when the number was connected. Genuka made that choice precisely to avoid the partner case described above.
A 190 in a Genuka WA response is therefore, in the vast majority of cases, an incident on
Genuka's side. It comes back like this:
{
"error": "send_config",
"message": "Authentication Error",
"meta": {
"errorClass": "config",
"retryable": false,
"code": 190,
"traceId": "AbC…"
}
}When creating a template, the same refusal comes back as 403 meta_rejected with the same meta
object (API reference). Either way:
- Do not retry in a loop.
retryable: false: the same call will fail the same way. - Contact Genuka support with the response's
x-request-idheader andmeta.traceId. - Do not ask the customer to reconnect straight away. Check
GET /api/v1/connectionsfirst.disconnectedmeans Meta reported the account as no longer shared with Genuka, or deleted, or that you released the number yourself. A customer who removed access restores it through the connect link, without using a new slot; a released number needs a free slot again; a deleted account, or one disabled by Meta (error 368), is not restored that way, and theaccount_updateevent forwarded to your webhooks tells you which case applies. If it still readsconnected, stay with Genuka support.
Do not confuse it with errors on your own API key, which never come from Meta:
401 missing_bearer_token (no header) and 401 invalid_token (unknown or revoked key), see
Authentication.
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: "order_confirmation", language: "en_US", variables: ["Awa", "ORD-1042"] },
}),
});
const json = await response.json();
if (response.status === 401) {
// Your Genuka key: missing, unknown or revoked. Nothing to do with Meta.
throw new Error(`API key refused: ${json.error}`);
}
if (json.meta?.code === 190 || json.meta?.code === 0) {
// Meta token refused: on Genuka's side. Stop and alert, do not retry.
console.error("Meta token refused", {
requestId: response.headers.get("x-request-id"),
traceId: json.meta.traceId,
});
}How do I prevent error 190?
- Never run production on the API Setup token. It exists to send a first test message, not to power a service that runs overnight.
- One system user token per environment, with only the WhatsApp permissions you need, kept in your secrets manager.
- Watch for revoked access. As a partner, the
account_updatewebhook reportsPARTNER_APP_UNINSTALLEDwhen a customer deauthenticates or uninstalls your app, andPARTNER_REMOVEDwhen an account is no longer shared with you (Meta, account_update webhook). Genuka WA forwards these events to your webhooks (account_updateevent), but of the two, onlyPARTNER_REMOVEDturns the numberdisconnected: after aPARTNER_APP_UNINSTALLED, it staysconnected. - Alert on the class, not on the text. In Genuka WA,
meta.errorClass: "config"covers token, permission and registration problems: a human has to look, and no retry will fix it.
Related error codes
- 0: Meta could not authenticate the app user; same remedy.
- 200: the token is valid but lacks access to the account or permission.
- 10: permission not granted or removed.
- 3: capability or permission missing for this endpoint.
FAQ
How long does a WhatsApp Cloud API access token last?
It depends on the type. A user token, like the one on the API Setup page, expires within a few hours. A system user token is long-lived, and you choose its expiration preference when you generate it.
Should I retry a send that failed with 190?
Not until the token has changed. The same token produces the same error; retrying only delays the alert.
Does my customer need to reconnect after a 190 on Genuka WA?
Only if their number shows disconnected in GET /api/v1/connections because they removed
Genuka's access: the account_update event forwarded to your webhooks confirms it. A deleted
account, or one disabled by Meta, is not restored by reconnecting. If the number still reads
connected, contact Genuka support with x-request-id and meta.traceId.
Should I regenerate my Genuka API key?
No. Your pk_live_… key authenticates your calls to Genuka WA, not to Meta. A refused key produces
a Genuka 401, never a 190.
Sources
WhatsApp error 10: permission denied — cause and fix
WhatsApp error 10 "Application does not have permission for this action": a missing permission, or an OTP template on an unverified business.
WhatsApp error 200: access denied (200-299) — fix
WhatsApp Cloud API error 200: missing token, revoked permission or a system user with no access to the account. How to diagnose and fix it.