# Errores

Todas las respuestas de error son `application/problem+json` (RFC 9457). **Decidí por `code`**: `error` y `detail` son texto para personas y pueden cambiar.

```json
{"type":"about:blank","title":"Conflict","status":409,"detail":"External reference already used by another delivery",
 "code":"EXTERNAL_REFERENCE_TAKEN","error":"External reference already used by another delivery"}
```

Ante un `5xx`, el cuerpo trae además `id` (también en el encabezado `X-Incident-Id`): mencionalo si escribís al courier.

| Status | `code` | Qué hacer |
| --- | --- | --- |
| 400 | `VALIDATION_FAILED` | Corregí el cuerpo o los parámetros; `detail` dice qué campo, en inglés como el resto de la API, y nunca repite el valor: `Invalid customerName` (valor o tipo incorrecto) o `Unknown field customer_name` (un campo que la API no acepta, por ejemplo un error de tipeo). |
| 400 | `INVALID_CURRENCY` | `currency` no es `"UYU"` ni `"USD"`, o mandaste `"USD"` sin `amountToCollect`. |
| 400 | `IDEMPOTENCY_KEY_REQUIRED` | Mandá un único `Idempotency-Key` válido (o `idempotencyKey` en cada ítem del lote). |
| 401 | `AUTHENTICATION_REQUIRED` | Falta `Authorization: Bearer …`. |
| 401 | `API_KEY_INVALID` | Clave mal copiada, inexistente o reemplazada por una rotación. |
| 401 | `API_KEY_REVOKED` | La clave fue revocada; pedí una nueva. |
| 403 | `API_KEY_SCOPE_MISSING` | La clave no tiene el permiso que la llamada necesita. |
| 403 | `PLAN_FEATURE_UNAVAILABLE` | El plan no incluye la función pedida (programación, cobro, comercios). Ver [Planes](planes.html). |
| 403 | `TEST_KEY_REQUIRED` | `simulate` sólo funciona con una clave de prueba. |
| 404 | `NOT_FOUND` | La entrega no existe o no la podés ver (otra empresa u otro comercio); o el comercio o la zona no son de la empresa. |
| 409 | `DELIVERY_STATE_INVALID` | La entrega ya no admite esa operación (por ejemplo, cancelar una que salió). Consultala y decidí. |
| 409 | `EXTERNAL_REFERENCE_TAKEN` | Ese número de pedido ya está en otra entrega del mismo comercio. Buscala con `?externalReference=`. |
| 409 | `IDEMPOTENCY_CONFLICT` | Esa `Idempotency-Key` ya se usó con otro cuerpo. |
| 409 | `PLAN_QUOTA_EXCEEDED` | Se alcanzó el cupo mensual de entregas del plan. Desde el 19/10/2026 la API ya no lo responde al crear: el pedido se acepta retenido (`quotaHeld: true`). |
| 409 | `PLAN_READ_ONLY` | La cuenta del courier está en solo lectura por falta de pago. |
| 409 | `ZONE_INACTIVE` / `CONFLICT` | La zona o el comercio están inactivos, o se alcanzó un límite (por ejemplo, 1000 entregas de prueba). |
| 410 | `SIGNED_URL_EXPIRED` | El enlace del comprobante venció: pedí el comprobante otra vez. |
| 410 | `EVIDENCE_EXPIRED` | La retención ya borró el comprobante (`expiredAt` dice cuándo). |
| 413 | `PAYLOAD_TOO_LARGE` | El cuerpo supera 8 KiB (512 KiB en el lote). |
| 415 | `UNSUPPORTED_MEDIA_TYPE` | Usá `Content-Type: application/json` (UTF-8). |
| 429 | `RATE_LIMITED` | Esperá los segundos de `Retry-After` ([límites](limites.html)). |
| 5xx | `INTERNAL_ERROR` / `SERVICE_UNAVAILABLE` | Reintentá con la **misma** `Idempotency-Key`; si persiste, informá el `id`. |

El catálogo completo de códigos de la plataforma está en el esquema `Problem` de la [referencia](referencia.html).
