Token endpoint
Intercambia códigos por tokens y renueva access tokens usando refresh tokens.
El token endpoint emite access_token y refresh_token. Soporta tres grant types: authorization_code, refresh_token y urn:ietf:params:oauth:grant-type:token-exchange. Esta página cubre los dos primeros; consulta Token Exchange para el tercero.
Endpoint
POST https://app.whatalo.com/oauth/token
Content-Type: application/x-www-form-urlencodedRate limits del token endpoint:
- 60 solicitudes por minuto por IP
- 30 solicitudes por minuto por
client_id
Al superar cualquiera de los dos límites recibirás HTTP 429 con el header Retry-After. Implementa backoff exponencial.
Autenticación de cliente
Los clientes confidenciales (los que tienen client_secret) deben autenticarse. Los clientes públicos (token_endpoint_auth_method: "none") no envían credenciales.
HTTP Basic (recomendado para clientes confidenciales)
Authorization: Basic BASE64(client_id:client_secret)Body params (alternativa)
client_id=abc123def456&client_secret=s3cr3t_v4lu3_xyz987wvu654Ambos métodos son equivalentes. No uses ambos a la vez.
Grant type: authorization_code
Intercambia el código de autorización recibido del flujo de autorización.
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic YWJjMTIzZGVmNDU2OihzM2NyM3RfdmFsdWU=
grant_type=authorization_code
&code=AUTH_CODE_DE_UN_SOLO_USO
&redirect_uri=https%3A%2F%2Fmi-app.com%2Foauth%2Fcallback
&client_id=abc123def456ghi789jkl012
&code_verifier=EL_CODE_VERIFIER_PKCEParámetros
| Parámetro | Requerido | Descripción |
|---|---|---|
grant_type | Sí | authorization_code |
code | Sí | Código recibido en el callback |
redirect_uri | Sí | Debe coincidir exactamente con la URI usada en el authorize |
client_id | Sí (si no va en Basic) | Tu client_id |
code_verifier | Sí | El verifier PKCE original (antes de hacer el hash) |
Respuesta
{
"access_token": "DlcGJFC7UmSx2fYKj7Bg3jhT9QgpyIzNcx7OGAoFu8U",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "LKr5XU5xyiD0XscBPSO9tm0DsSK2AKsWL2fOe9an6v8",
"scope": "read:products read:orders"
}Grant type: refresh_token
Cuando el access_token expira (cada hora), usa el refresh_token para obtener uno nuevo.
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic YWJjMTIzZGVmNDU2OihzM2NyM3RfdmFsdWU=
grant_type=refresh_token
&refresh_token=LKr5XU5xyiD0XscBPSO9tm0DsSK2AKsWL2fOe9an6v8
&client_id=abc123def456ghi789jkl012Respuesta
{
"access_token": "00e1NyN_TYwjunXFjnNpMcs6PdJgXqoVMfeTfJgkhP0",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "n-zDToBmLXUEOrPtOH4usLAYOxZkmyU1WKwqOYJRaZ8",
"scope": "read:products read:orders"
}La rotación de refresh tokens es estricta. El refresh token anterior se revoca inmediatamente. Si presentas un token ya revocado, Whatalo revoca toda la familia de tokens — el usuario deberá re-autorizar desde cero. Evita condiciones de carrera: serializa los refreshes en tu infraestructura.
Downscoping opcional
Puedes solicitar un subconjunto de los scopes originalmente concedidos:
&scope=read:productsSolicitar scopes más amplios que los concedidos devuelve invalid_scope.
Duraciones de tokens
| Token | Duración | Notas |
|---|---|---|
access_token | 1 hora | Envíalo como Authorization: Bearer <token> |
refresh_token | 30 días | Rota en cada uso — guarda siempre el nuevo |
authorization_code | 10 minutos | De un solo uso, vinculado al PKCE verifier |
Usando el access token
GET https://api.whatalo.com/v1/products
Authorization: Bearer DlcGJFC7UmSx2fYKj7Bg3jhT9QgpyIzNcx7OGAoFu8UManejo de errores
| Error | HTTP | Causa |
|---|---|---|
invalid_grant | 400 | Código expirado, ya usado, o code_verifier incorrecto |
invalid_client | 401 | Credenciales de cliente inválidas o faltantes |
invalid_request | 400 | Parámetro faltante o malformado |
invalid_scope | 400 | Scope solicitado excede los concedidos |
rate_limit_exceeded | 429 | Límite de solicitudes superado — ver Retry-After |
Ver la referencia completa en Errores OAuth.