Introspección de tokens (RFC 7662)
Valida Bearer tokens de Whatalo desde tu Resource Server.
El endpoint de introspección (RFC 7662) permite que tu Resource Server verifique si un Bearer token es válido y activo, y obtenga los claims asociados.
Endpoint
POST https://app.whatalo.com/oauth/introspect
Content-Type: application/x-www-form-urlencodedAutenticación requerida
La introspección requiere que el Resource Server se autentique como cliente OAuth confidencial. Usa HTTP Basic o body params:
POST /oauth/introspect
Content-Type: application/x-www-form-urlencoded
Authorization: Basic BASE64(rs_client_id:rs_client_secret)
token=EL_BEARER_TOKEN_A_VALIDARO con body params:
token=EL_BEARER_TOKEN_A_VALIDAR
&client_id=rs_client_id
&client_secret=rs_client_secretLas credenciales del Resource Server (client_id y client_secret) corresponden a un cliente OAuth confidencial registrado para ese propósito. Si estás construyendo un MCP server u otro Resource Server, regístralo via Dynamic Client Registration con token_endpoint_auth_method: "client_secret_post" (o client_secret_basic).
Respuesta — token activo
{
"active": true,
"scope": "read:products read:orders",
"client_id": "abc123def456ghi789jkl012",
"sub": "usr_7f3a9b2c1d4e5f6a",
"exp": 1777719020,
"iat": 1777715420,
"token_type": "Bearer",
"aud": "https://api.whatalo.com",
"iss": "https://app.whatalo.com",
"whatalo_store_id": "str_8k2m4n6p"
}Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
active | boolean | true si el token es válido y no ha expirado ni sido revocado |
scope | string | Scopes concedidos, separados por espacio |
client_id | string | client_id del cliente OAuth que obtuvo el token |
sub | string | Identificador del usuario que autorizó el acceso |
exp | number | Timestamp UNIX de expiración |
iat | number | Timestamp UNIX de emisión |
token_type | string | Siempre Bearer |
aud | string | Audience. Refleja el parámetro resource (RFC 8707) si fue enviado en el authorize |
iss | string | Siempre https://app.whatalo.com |
whatalo_store_id | string | ID público de la tienda a la que está vinculado el token — el mismo ID corto usado en las URLs de Whatalo |
El campo whatalo_store_id es clave para los Resource Servers multitenant. Te indica exactamente qué tienda autorizó el acceso, de modo que puedes enrutar las operaciones al contexto correcto sin depender de headers adicionales.
Respuesta — token inactivo
{ "active": false }Los tokens inactivos (expirados, revocados, o simplemente no existentes) devuelven únicamente { "active": false }. No se expone ningún otro claim para tokens inválidos.
Vinculación de audience (RFC 8707)
Si el cliente OAuth incluyó el parámetro resource al iniciar el flujo de autorización, el campo aud del token refleja ese valor. Tu Resource Server puede validar que el token fue emitido para él:
const { active, aud } = await introspect(bearerToken);
if (!active) return unauthorized();
if (aud !== "https://mi-resource-server.com") return unauthorized();Recomendaciones de caché
| Caso | Recomendación |
|---|---|
Token active: true | Cachea hasta 60 segundos como máximo |
Token active: false | No cachees — el resultado puede cambiar si el token se renueva |
Si cacheas respuestas active: true por más de 60 segundos, un token revocado seguirá siendo aceptado por tu Resource Server durante ese período. Ver Revocación para entender el comportamiento de revocación en cascada.
Ejemplo completo en Node.js
async function introspectToken(bearerToken, rsClientId, rsClientSecret) {
const credentials = Buffer.from(`${rsClientId}:${rsClientSecret}`)
.toString("base64");
const res = await fetch("https://app.whatalo.com/oauth/introspect", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": `Basic ${credentials}`,
},
body: new URLSearchParams({ token: bearerToken }),
});
const data = await res.json();
if (!data.active) {
throw new Error("Token is not active");
}
// data.whatalo_store_id tells you which store was authorized
return data;
}Siguiente paso
Para revocar un token activo, usa el endpoint de revocación.