# Errores

> Cómo informa de los errores la API de Emailit. Formatos del cuerpo de respuesta, códigos de estado HTTP y su significado, y soluciones para los mensajes de error más habituales.

La API de Emailit usa códigos de estado HTTP para indicarte si una petición ha funcionado. Los códigos del rango `2xx` indican éxito, los códigos `4xx` indican que hay que cambiar algo en la petición y los códigos `5xx` indican que algo ha fallado por nuestra parte. Esta página describe los cuerpos de error, todos los códigos de estado que devuelve la API y cómo solucionar los errores más habituales.

## Formatos de las respuestas de error

Todo cuerpo de error es un objeto JSON con un campo `error`. Su forma exacta depende de dónde falló la petición. Escribe la gestión de errores para que lea `error`, después `message` si está presente y, por último, cualquier campo adicional que documente el endpoint.

### Errores de la petición

Los fallos de autenticación, los errores de permisos, el JSON mal formado y otros errores que se producen antes de que se ejecute un endpoint usan el formato de error HTTP estándar:

```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "API key required"
}
```

| Campo | Descripción |
| --- | --- |
| `statusCode` | El código de estado HTTP. |
| `error` | La frase de motivo HTTP, como `Unauthorized` o `Forbidden`. |
| `message` | Qué ha fallado, explicado en lenguaje sencillo. |

### Errores de validación

Cuando un parámetro de consulta o un campo del cuerpo tiene un tipo incorrecto, falta o está fuera de rango, la API rechaza la petición con `400` antes de ejecutarla y enumera cada problema en `details`:

```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation error",
  "details": [
    {
      "instancePath": "/limit",
      "schemaPath": "#/properties/limit/maximum",
      "keyword": "maximum",
      "params": { "comparison": "<=", "limit": 100 },
      "message": "must be <= 100"
    }
  ]
}
```

`instancePath` señala el campo (`/limit`, `/to`, `/attachments/0/filename`) y `message` describe la regla que incumple. En algunos endpoints, como [Enviar un email](/es/docs/api-reference/emails/send/), estos errores solo devuelven `{"error": "Bad Request"}`.

### Errores de recursos

Los errores que genera un endpoint, como un objeto que no existe o un nombre duplicado, devuelven `error` y a menudo `message`:

```json
{
  "error": "Email not found",
  "message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}
```

Algunos errores añaden campos que te ayudan a resolver el problema:

| Campo | Se devuelve con | Contiene |
| --- | --- | --- |
| `existing` | `409` cuando creas un dominio, una clave de API, una lista de contactos, un contacto o un suscriptor duplicado | El objeto que ya existe, para que puedas usarlo en su lugar. |
| `usage` | `422` cuando se alcanza un límite del plan | `used`, `limit` y, en las listas de contactos, `plan`. |
| `required_plan` | `403` con `error: "plan_required"` | El plan más bajo que incluye la función, como `pro`. |
| `code` | Algunos errores `403` y `422` | Un código estable y legible por máquinas, como `unverified_workspace_recipient` o `events_offset_too_large`. |
| `missing` | `404` de [Actualizar contactos de forma masiva](/es/docs/api-reference/contacts/bulk/) | Los ID de los contactos que no se encontraron. |

### Errores de validación del envío

[Enviar un email](/es/docs/api-reference/emails/send/) y [Reenviar un email](/es/docs/api-reference/emails/forward/) comprueban todo el mensaje de una vez y devuelven todos los problemas en `validation_errors`:

```json
{
  "error": "Validation failed",
  "validation_errors": [
    "Missing required field: subject",
    "Invalid to email address at index 1: ada@example"
  ]
}
```

### Errores por campo

Las plantillas, las campañas y las automatizaciones devuelven los problemas de validación agrupados por campo:

```json
{
  "message": "Validation failed",
  "errors": {
    "alias": ["Alias must contain only lowercase letters (a-z), numbers (0-9), underscores (_), and hyphens (-)"]
  }
}
```

### Errores de límite de velocidad

Las respuestas `429` de los endpoints de envío incluyen el límite que has alcanzado y cuánto tiempo debes esperar. Consulta [Límites de velocidad](/es/docs/api-reference/rate-limits/).

```json
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Maximum 2 messages per second allowed.",
  "limit": 2,
  "current": 2,
  "retry_after": 1
}
```

## Códigos de estado HTTP

| Código | Significado | Causas habituales en la API de Emailit |
| --- | --- | --- |
| `200` | OK | La petición ha funcionado. Los envíos, las actualizaciones, las eliminaciones y las lecturas devuelven `200`. |
| `201` | Created | Se ha creado un dominio, una clave de API, una lista de contactos, un suscriptor, un contacto, una plantilla, un webhook u otro objeto. |
| `202` | Accepted | Se ha aceptado la subida de un informe DMARC para procesarla. |
| `204` | No Content | Se ha eliminado un formulario. La respuesta no tiene cuerpo. |
| `400` | Bad Request | JSON no válido, falta un campo obligatorio, un valor tiene un tipo incorrecto o está fuera de rango, la `Idempotency-Key` no es válida o no hay campos que actualizar. |
| `401` | Unauthorized | Falta la clave de API, no es válida, se eliminó o se regeneró, o un token OAuth caducó. Consulta [Autenticación](/es/docs/api-reference/authentication/#authentication-errors). |
| `402` | Payment Required | El espacio de trabajo no tiene créditos suficientes para el envío, el reintento o la verificación. |
| `403` | Forbidden | El permiso de la clave no da acceso al endpoint, una clave limitada a un dominio envió desde otro dominio, el espacio de trabajo está suspendido o aún no está verificado, el dominio de envío está pausado o la función requiere un plan superior. |
| `404` | Not Found | El objeto no existe en este espacio de trabajo, o un alias de plantilla no tiene ninguna versión publicada. |
| `409` | Conflict | Ya existe un objeto con el mismo nombre o email, o todavía se está procesando una petición con la misma `Idempotency-Key`. |
| `413` | Payload Too Large | El email, una vez compuesto, supera los 40 MB, o la subida de un informe DMARC supera los 10 MB. |
| `422` | Unprocessable Entity | La petición es válida, pero no se puede llevar a cabo ahora: el dominio de `from` no está verificado, no se pudo obtener un adjunto, el estado del email no permite cancelarlo ni reintentarlo, su contenido ya se purgó o se alcanzó un límite del plan. |
| `429` | Too Many Requests | El espacio de trabajo alcanzó su límite de envío por segundo o diario, o el límite de reenvíos por hora. |
| `500` | Internal Server Error | Algo ha fallado por nuestra parte. Reintenta con espera exponencial y contacta con soporte si el problema persiste. |
| `503` | Service Unavailable | Una interrupción temporal de una dependencia, como el almacén de idempotencia o la base de datos de autenticación. Reintenta con espera exponencial. |

## Errores habituales y cómo solucionarlos

| Estado | `error` | Causa | Solución |
| --- | --- | --- | --- |
| `400` | `Validation failed` | A un envío le falta `from`, `to`, `subject` o el contenido, o tiene una dirección o un adjunto no válidos. | Corrige cada elemento que aparece en `validation_errors`. |
| `400` | `Invalid JSON in request body` (en `message`) | El cuerpo no es JSON válido. | Revisa las comillas y las comas finales, y envía `Content-Type: application/json`. |
| `400` | `Invalid Idempotency-Key` | La clave tiene más de 256 caracteres o contiene caracteres distintos de letras, dígitos, `-` y `_`. | Usa un UUID o un valor seguro similar. |
| `402` | `Insufficient credits` | Se acabaron los créditos. Cada destinatario cuesta un crédito. | Compra créditos o activa la [recarga automática](/es/docs/billing/auto-refill/). |
| `403` | `Workspace not verified` | El espacio de trabajo está en modo sandbox y un destinatario no es miembro del espacio de trabajo. | Solicita el [acceso de producción](/es/docs/workspaces/production-access/). |
| `403` | `Domain paused` | El envío desde este dominio está pausado por su [salud de envío](/es/docs/deliverability/sending-health/). | Soluciona el problema de rebotes o quejas y después contacta con soporte. |
| `403` | `Domain not authorized` | La clave de API está limitada a otro dominio de envío. | Envía desde el dominio de la clave o usa otra clave. |
| `403` | `plan_required` | La función, como los informes DMARC o los filtros de webhooks, no está incluida en tu plan. | Cambia al plan indicado en `required_plan`. |
| `403` | `mjml_alpha` | La petición crea o cambia MJML, o llama a un endpoint de MJML. MJML está en alfa y solo está abierto al equipo de Emailit. | Usa otro editor u otro tipo de contenido. Consulta [Editores y API de MJML](/es/docs/templates/mjml/#who-can-use-mjml). |
| `404` | `Template not found` | El ID de la plantilla no existe, o el alias no tiene ninguna versión publicada. | [Publica](/es/docs/api-reference/templates/publish/) una versión de la plantilla. |
| `409` | `… already exists` | Has creado un objeto con un nombre o un email que ya está en uso. | Usa el objeto de `existing` o elige otro nombre. |
| `409` | `Idempotency key in progress` | Otra petición con la misma clave aún no ha terminado. | Espera un momento y reintenta con la misma clave. |
| `413` | `Message too large` | El email, adjuntos incluidos, supera los 40 MB. | Envía los archivos grandes como enlaces en lugar de adjuntos. |
| `422` | `Domain not verified` | La dirección de `from` no pertenece a un dominio de envío verificado de este espacio de trabajo. | [Verifica el dominio](/es/docs/domains/verification/) o cambia `from`. |
| `422` | `Attachment error` | No se pudo obtener la `url` de un adjunto en 30 segundos, no es accesible o supera los 25 MB. | Comprueba que la URL sea pública y que el archivo no sea demasiado grande, o envía `content` en su lugar. |
| `422` | `Cannot cancel email`, `Cannot retry email`, `Cannot update email` | El estado del email no permite la acción, faltan menos de 3 minutos para su hora programada o su contenido se purgó. | Comprueba el `status` del email. Consulta las reglas de cada endpoint. |
| `422` | `Page is too deep` | Has paginado más allá del desplazamiento 2500 de [Listar eventos](/es/docs/api-reference/events/list/). | Acota los resultados con los filtros `type` o `created_at`. |
| `429` | `Rate limit exceeded`, `Daily limit exceeded` | El espacio de trabajo alcanzó su límite de envío. | Espera `retry_after` segundos. Consulta [Límites de velocidad](/es/docs/api-reference/rate-limits/). |

## Reintentar de forma segura

- Reintenta las respuestas `429`, `500` y `503` tras una espera. Usa la cabecera `retry-after` cuando esté presente y, si no, una espera exponencial. [Límites de velocidad](/es/docs/api-reference/rate-limits/#retry-with-backoff) incluye código de ejemplo.
- No reintentes otros errores `4xx` sin cambios. Seguirán fallando igual hasta que corrijas la petición.
- Cuando reintentes un envío tras un tiempo de espera agotado o un error `5xx`, reutiliza la misma [`Idempotency-Key`](/es/docs/api-reference/idempotency/) para que el email no se envíe dos veces.

## Ver también

  - [Autenticación](/es/docs/api-reference/authentication/): Credenciales, permisos y todos los errores de autenticación.
  - [Límites de velocidad](/es/docs/api-reference/rate-limits/): Límites de envío, cabeceras y espera exponencial.
  - [Idempotencia](/es/docs/api-reference/idempotency/): Reintenta envíos sin enviar dos veces.
  - [Registros de peticiones](/es/docs/logs/request-logs/): Consulta la petición y la respuesta de cada llamada a la API que haya fallado.

---
Fuente: https://emailit.com/es/docs/api-reference/errors/
