# Catálogo de errores

> Todos los códigos que la API puede emitir, con su status HTTP, su semántica de reintento y qué hacer con cada uno.



{/* AUTO-GENERATED by @emisso/codegen. DO NOT EDIT. */}

Cada error llega con la misma forma, pensada para que un humano o un agente sepan qué hacer sin adivinar. Ejemplo real (falta el `connectionId` en una tool que lo exige):

```json
{
  "error": {
    "code": "validation_error",
    "message": "'sii.rcv.consultar' requiere una conexión concreta.",
    "suggested_fix": "Pasa el connectionId de la conexión de 'sii' (MCP: campo 'connectionId' de execute; REST: header 'X-Connect-Connection'). Lístalos con la tool 'conexiones.estado.consultar'.",
    "request_id": "req_5tYw2nRk88Ma"
  },
  "meta": {
    "request_id": "req_5tYw2nRk88Ma",
    "tool_id": "sii.rcv.consultar",
    "plane": "action",
    "latency_ms": 12,
    "audit_status": "recorded"
  }
}
```

Reglas de manejo:

* Decide por `code`, nunca por el texto: `message` puede cambiar, los códigos no.
* `suggested_fix` está escrito para ejecutarse: si tu agente recibe el error crudo, ya sabe el paso siguiente.
* `request_id` correlaciona con la fila de la bitácora y es lo primero que pedirá soporte. Guárdalo en tus logs.
* Reintenta solo lo reintentable (columna de cada tabla). El SDK reintenta GET por su cuenta; los `execute` (POST) nunca se reintentan solos: reintentar a ciegas una acción regulada es la receta del doble pago.

## Petición [#petición]

| Código                    | HTTP | Reintentable | Qué significa                                                      | Qué hacer                                                                                                                        |
| ------------------------- | ---- | ------------ | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `validation_error`        | 400  | no           | El input no cumple el esquema de la tool.                          | Revisa error.details: viene el detalle campo a campo. Corrige el input y reenvía.                                                |
| `malformed_request`       | 400  | no           | El cuerpo no es JSON válido.                                       | Verifica la serialización y el Content-Type antes de reenviar.                                                                   |
| `unsupported_media_type`  | 415  | no           | El Content-Type no es application/json.                            | Envía el cuerpo con el header Content-Type: application/json.                                                                    |
| `payload_too_large`       | 413  | no           | El cuerpo supera el límite de 256 KB.                              | Reduce el payload; si es una lista, pagina con cursor.                                                                           |
| `idempotency_conflict`    | 409  | no           | Esa Idempotency-Key ya se usó con un cuerpo distinto.              | Genera una clave nueva para una operación nueva; reutiliza la clave solo para reintentar la misma.                               |
| `idempotency_in_progress` | 409  | sí           | Otro intento con esa misma Idempotency-Key todavía está corriendo. | Espera unos segundos y reintenta con la MISMA clave. Generar una nueva para la misma operación es lo que duplica el efecto.      |
| `tool_not_found`          | 404  | no           | Ese id de tool no existe para tu organización.                     | Confirma el id con conexiones.sistemas.listar o search\_docs. También cubre conectores que tu organización no tiene habilitados. |

## Autenticación y permisos [#autenticación-y-permisos]

| Código              | HTTP | Reintentable | Qué significa                                                     | Qué hacer                                                                                                               |
| ------------------- | ---- | ------------ | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `unauthorized`      | 401  | no           | Falta el bearer o el token no es válido.                          | Envía Authorization: Bearer connect\_sk\_… con una API key vigente. Si usas OAuth, renueva el access token.             |
| `forbidden`         | 403  | no           | La identidad autenticó pero no tiene permiso para esta operación. | Confirma el rol y la organización de la credencial que estás usando.                                                    |
| `scope_not_granted` | 403  | no           | La API key no tiene el scope que la tool exige.                   | Crea o edita la key en /api-keys con el scope requerido. Recuerda: scopes vacíos significan cero autoridad, no comodín. |

## Conexiones y sincronización [#conexiones-y-sincronización]

| Código                           | HTTP | Reintentable | Qué significa                                                                                                                         | Qué hacer                                                                                                                                                                                |
| -------------------------------- | ---- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `connection_ambiguous`           | 409  | no           | Hay más de una conexión de ese sistema y la llamada no dijo cuál.                                                                     | Indica la conexión: header X-Connect-Connection en REST, campo connectionId en MCP y el SDK.                                                                                             |
| `connection_busy`                | 409  | sí           | Otra operación tiene tomada esta conexión en este momento.                                                                            | Espera unos segundos y reintenta. El candado es por conexión y se suelta solo.                                                                                                           |
| `connection_disabled`            | 403  | no           | La conexión existe pero está deshabilitada.                                                                                           | Reactívala en /connections o usa otra conexión del mismo sistema.                                                                                                                        |
| `connection_credential_required` | 428  | no           | La conexión no tiene una credencial viva: nunca se vinculó, venció o fue revocada.                                                    | Crea un enlace con conexiones.enlace.crear (modo reconectar si la conexión ya existe) y pide a la persona que entregue la credencial de nuevo. No reintentes con la credencial anterior. |
| `connection_identity_mismatch`   | 409  | no           | La respuesta del sistema externo no corresponde a la identidad de esta conexión, o no trajo la prueba de identidad que Connect exige. | No reintentes: la respuesta es determinista. Revisa qué RUT tiene guardado la conexión y vuelve a vincular la credencial si no es el correcto.                                           |
| `connected_account_required`     | 428  | no           | La tool exige una cuenta conectada del usuario y no existe.                                                                           | Completa el flujo de autorización que indica el challenge de la respuesta.                                                                                                               |
| `connection_session_pending`     | 409  | sí           | El sistema exige un desafío de navegador y todavía no hay una sesión de portal acuñada.                                               | Ejecuta la sincronización de esa conexión (ella acuña la sesión) o espera la programada, y reintenta.                                                                                    |
| `connection_sync_in_progress`    | 409  | sí           | Ya corre una sincronización de esa conexión para ese período.                                                                         | Espera a que termine y reintenta, o consulta directamente: puede que ya haya datos.                                                                                                      |
| `connector_onboarding_required`  | 428  | no           | El sistema externo exige completar su configuración antes de operar. En Notta, por ejemplo, el certificado digital y los folios.      | Lee el mensaje: dice qué falta. Se completa en el portal de ese sistema, no en Connect, y después la llamada funciona sin cambios.                                                       |
| `too_many_pending`               | 429  | sí           | La cola de sincronizaciones pendientes de la conexión está llena.                                                                     | Deja terminar los trabajos en curso antes de encolar más.                                                                                                                                |
| `sync_job_not_found`             | 404  | no           | Ese id de trabajo de sincronización no existe en tu organización.                                                                     | Usa los job\_ids que devolvió el POST que encoló el trabajo.                                                                                                                             |
| `alcance_not_enabled`            | 403  | no           | La conexión no tiene habilitado el módulo de datos que la tool pide.                                                                  | Habilita el alcance en /connections o quítalo del input de la sincronización.                                                                                                            |
| `alcance_scheme_unsupported`     | 422  | no           | El módulo de datos pedido no está disponible con el tipo de acceso de esta conexión.                                                  | Crea una conexión con el otro acceso, o quita ese módulo del input de la sincronización.                                                                                                 |

## Límites y plan [#límites-y-plan]

| Código                    | HTTP | Reintentable | Qué significa                                                                                                                                             | Qué hacer                                                                                                 |
| ------------------------- | ---- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `rate_limited`            | 429  | sí           | Superaste un límite de tasa.                                                                                                                              | Espera y reintenta con backoff exponencial.                                                               |
| `quota_exceeded`          | 429  | no           | Esta conexión alcanzó su cupo de llamadas del período. Tus demás conexiones siguen funcionando.                                                           | Espera el período siguiente o pide una ampliación. Subir de plan no cambia el cupo, y reintentar tampoco. |
| `feature_not_in_plan`     | 403  | no           | Esa función no está incluida en tu plan.                                                                                                                  | Revisa /billing para habilitarla.                                                                         |
| `billing_past_due`        | 402  | no           | La organización tiene un pago vencido. Se pausan la sincronización y las conexiones nuevas; la lectura de lo ya persistido sigue funcionando.             | Regulariza el pago en /billing. Reintentar no paga la deuda.                                              |
| `payment_method_required` | 402  | no           | La prueba terminó y no hay una tarjeta registrada. Se pausan la sincronización y las conexiones nuevas; la lectura de lo ya persistido sigue funcionando. | Agrega un medio de pago en /billing. No hay ninguna deuda que regularizar: falta la tarjeta.              |
| `connector_plan_limit`    | 402  | no           | Se agotó la cuota del plan que tu organización tiene EN ESE SISTEMA. No es un límite de Connect.                                                          | Sube el plan en el portal de ese sistema. El mensaje trae el enlace.                                      |

## Sistema externo [#sistema-externo]

| Código                         | HTTP | Reintentable | Qué significa                                                                    | Qué hacer                                                                                                    |
| ------------------------------ | ---- | ------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `upstream_error`               | 502  | sí           | El sistema externo (SII, banco) falló o respondió mal.                           | Reintenta más tarde. Si persiste, el problema está en el sistema externo, no en tu integración.              |
| `upstream_unexpected_response` | 502  | no           | El sistema externo respondió con una forma que Connect no reconoce.              | No reintentes: la respuesta es determinista. Repórtalo con el request\_id para que actualicemos el conector. |
| `timeout`                      | 504  | sí           | La operación superó su tiempo máximo, casi siempre esperando al sistema externo. | Reintenta. Para sincronizaciones largas usa la vía asíncrona y consulta el estado del trabajo.               |

## Webhooks [#webhooks]

| Código                       | HTTP | Reintentable | Qué significa                                          | Qué hacer                                                                     |
| ---------------------------- | ---- | ------------ | ------------------------------------------------------ | ----------------------------------------------------------------------------- |
| `webhook_endpoint_not_found` | 404  | no           | Ese endpoint de webhook no existe en tu organización.  | Lista tus endpoints con GET /v1/webhooks y usa un id vigente.                 |
| `webhook_delivery_not_found` | 404  | no           | Esa entrega de webhook no existe para ese endpoint.    | Lista las entregas con GET /v1/webhooks/\{id}/deliveries y usa un id vigente. |
| `invalid_webhook_url`        | 422  | no           | La URL del webhook no es válida para recibir entregas. | Usa una URL https pública. Direcciones internas o no resolubles se rechazan.  |

## Internos de Connect [#internos-de-connect]

| Código                  | HTTP | Reintentable | Qué significa                                                         | Qué hacer                                                             |
| ----------------------- | ---- | ------------ | --------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `service_unavailable`   | 503  | sí           | Connect no pudo atender la petición por una falla transitoria propia. | Reintenta con backoff. No es un problema de tu petición ni de tu key. |
| `output_contract_error` | 500  | no           | El resultado interno no cumplió el contrato de salida de la tool.     | Es un defecto de Connect. Repórtalo con el request\_id.               |
| `handler_error`         | 500  | no           | La tool falló de forma no clasificada.                                | Repórtalo con el request\_id si persiste. No reintentes a ciegas.     |
| `internal_error`        | 500  | no           | Error interno no clasificado de Connect.                              | Repórtalo con el request\_id. No reintentes a ciegas.                 |
| `not_implemented`       | 501  | no           | La operación existe en el contrato pero aún no está implementada.     | Consulta el changelog o espera su disponibilidad.                     |
