> ## Documentation Index
> Fetch the complete documentation index at: https://docs.edtools.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Errores y diagnóstico

> Los quince códigos del Client API, qué hacer con cada uno y cómo pedir soporte sin filtrar secretos.

Todos los errores tienen la misma forma:

```json theme={null}
{
  "error": {
    "code": "SCOPE_REQUIRED",
    "message": "Missing required scope: students:read.",
    "requestId": "..."
  }
}
```

<Tip>
  Programa contra `code`, nunca contra `message`. El código es el contrato; el mensaje está para que lo lea una persona y puede cambiar.
</Tip>

## Catálogo completo

### Autenticación y acceso

| Código                | HTTP | Qué pasó                                        | Qué hacer                                                                     |
| --------------------- | ---- | ----------------------------------------------- | ----------------------------------------------------------------------------- |
| `CLIENT_API_DISABLED` | 403  | El Client API no está habilitado en el entorno. | Revisar `EDTOOLS_CLIENT_API_ENABLED=1`. Es configuración de EdTools, no tuya. |
| `INVALID_TOKEN`       | 401  | Token ausente o malformado.                     | Revisar la cabecera `Authorization: Bearer ...`.                              |
| `TOKEN_REVOKED`       | 401  | La key fue revocada.                            | Pedir una nueva. Alguien la revocó a propósito.                               |
| `TOKEN_EXPIRED`       | 401  | La key pasó su fecha de expiración.             | Rotar. Y poner el recordatorio de rotación esta vez.                          |
| `TENANT_DISABLED`     | 403  | La institución está deshabilitada.              | No se resuelve por API: hablar con EdTools.                                   |
| `IP_NOT_ALLOWED`      | 403  | La IP de origen no está en la allowlist.        | Agregar la IP o el CIDR de salida real del cliente. Ojo con los proxies.      |

### Permisos

| Código                | HTTP | Qué pasó                                                 | Qué hacer                                                                                        |
| --------------------- | ---- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `SCOPE_REQUIRED`      | 403  | Al token le falta el scope del endpoint.                 | Agregar el scope, o usar otro token. Ver [Scopes](/client-api/scopes).                           |
| `MODULE_DISABLED`     | 403  | La institución no tiene ese módulo encendido.            | Revisar `platform_integrations` y el módulo funcional. Ver [Módulos](/plataforma/modulos).       |
| `SOR_WRITE_FORBIDDEN` | 403  | Ese dominio de datos no admite escrituras de este token. | Revisar `sorByDomain` y `masterDomains` en `/me`. Ver [Multi-tenancy](/plataforma/multi-tenant). |

### Petición

| Código                     | HTTP | Qué pasó                                            | Qué hacer                                                     |
| -------------------------- | ---- | --------------------------------------------------- | ------------------------------------------------------------- |
| `VALIDATION_ERROR`         | 400  | El cuerpo o los parámetros no pasan el esquema.     | El detalle dice qué campo. Contrastar con la Referencia.      |
| `NOT_FOUND`                | 404  | El recurso no existe **en esta institución**.       | Verificar el id. Recuerda que el tenant sale del token.       |
| `CONFLICT`                 | 409  | El estado actual no admite la operación.            | Releer el recurso antes de reintentar.                        |
| `IDEMPOTENCY_KEY_REQUIRED` | 400  | Falta `Idempotency-Key` en un `POST` que la exige.  | Ver [Idempotencia](/client-api/idempotencia).                 |
| `IDEMPOTENCY_CONFLICT`     | 409  | Esa clave ya se usó con otro cuerpo, método o path. | Usar una clave nueva, o mandar exactamente la misma petición. |
| `RATE_LIMITED`             | 429  | Se pasó del tope por minuto.                        | Esperar a `X-RateLimit-Reset`. Ver abajo.                     |

Cualquier `5xx` es problema de EdTools: guarda el `requestId` y repórtalo.

## Rate limits

Toda respuesta autenticada trae el estado del tope:

```http theme={null}
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 119
X-RateLimit-Reset: 1778284800
```

<Warning>
  El tope es **por token y por minuto**. Si repartes el trabajo entre varios procesos con el mismo token, comparten el presupuesto.
</Warning>

Al recibir `429`, espera hasta `X-RateLimit-Reset` (epoch en segundos) en vez de reintentar de inmediato. Para cargas grandes, pagina con `page` y `limit` y usa `updatedSince` para traer solo lo que cambió: casi siempre el problema no es el tope, es que estás pidiendo todo el catálogo cada hora.

## Cuando toca pedir ayuda

En **Ajustes → API e integraciones → Actividad** se busca por path, API key, IP, user-agent o `requestId`. El detalle de cada llamada trae el endpoint, el scope exigido, el Source of Record, los módulos requeridos, el código de error y el estado del rate limit.

Ahí mismo hay un resumen copiable pensado para compartir: **no lleva payloads sensibles ni la cabecera `Authorization`**.

<Warning>
  Nunca mandes el token en un ticket, un chat o un correo. Para diagnosticar basta con `requestId`, el nombre de la key, el sistema de origen y la ventana horaria.
</Warning>
