# Consultar un envío

Consulta el resultado de un envío ya admitido con GET /v1/email/:messageId.

**GET https://api.e-comms.dev/v1/email/:messageId**

El resultado de un envío ya admitido. No cuesta cuota: una organización sobre su límite igual puede leer lo que ya envió.

Status: `200`

### Parámetros de ruta

- `messageId` `string` — Obligatorio. El id que devolvió POST /v1/email en su propio results[].messageId.

### Parámetros de consulta

Ninguno.

### Encabezados

- `Authorization` `string` — Obligatorio. `Bearer ek_live_<clave>`.

### Atributos de la solicitud

Ninguno.

### Atributos de la respuesta

- `id` `string` — Obligatorio. El mismo id que el parámetro de ruta.
- `address` `string` — Obligatorio. La dirección de este destinatario.
- `status` `string` — Obligatorio. claimed, sent, suppressed, failed o unknown — ver Notas.
- `deliveryStatus` `string | null` — Obligatorio. null hasta la primera entrega de webhook. Después, deferred, delivered, rejected, bounced o complained — ver Notas.
- `failureReason` `string | null` — Obligatorio. null salvo que status sea failed, donde trae el motivo del proveedor.
- `createdAt` `string` — Obligatorio. Cuándo se admitió el envío. Nunca null.
- `sentAt` `string | null` — Obligatorio. null hasta que el intento de envío mismo tuvo éxito o falló.
- `deliveredAt` `string | null` — Obligatorio. null hasta que deliveryStatus llega a delivered.

## Notas

- **`status` es del intento de envío, no de la entrega.** `claimed` es el único valor antes de
  llamar al proveedor; `sent` y `failed` describen si esa llamada tuvo éxito; `unknown` es lo
  que deja una interrupción entre la reclamación y la respuesta del proveedor, después de que
  un reintento acotado ya tuvo su oportunidad — nunca una entrega fallida en sí.
- **`deliveryStatus` es una escalera que nunca retrocede**, la misma que documenta la
  [referencia de webhooks](/docs/reference/webhooks): `deferred`, `delivered`, `rejected`,
  `bounced` y `complained`, en el orden en que puede llegar una queja tardía por encima de una
  entrega ya registrada.
- **No cuesta cuota:** una organización sobre su límite igual puede leer lo que ya envió.
- **Leer pide su propio permiso.** Esta ruta exige `messages:read`; enviar exige `messages:send`. Una clave emitida solo con `messages:send` puede enviar, pero recibe `403` al consultar un envío, así que crea la clave con los dos permisos si va a hacer ambas cosas.

## Errores

| Estado | Código | Causa |
| --- | --- | --- |
| `403` | `forbidden` | La clave no tiene el permiso `messages:read`. Una clave emitida solo con `messages:send` recibe este 403 al leer. |
| `404` | `not_found` | El mensaje no existe, o existe para otra organización — la respuesta nunca revela cuál de las dos. |

## Solicitud

```bash
curl https://api.e-comms.dev/v1/email/01a0ba31-3fe4-7cc4-a1c6-64bdaaa5d99c \
  -H "Authorization: Bearer ek_live_<tu-clave>"
```

```js
const response = await fetch(
  "https://api.e-comms.dev/v1/email/01a0ba31-3fe4-7cc4-a1c6-64bdaaa5d99c",
  { headers: { Authorization: "Bearer ek_live_<tu-clave>" } },
)

const body = await response.json()
```

```python
import requests

response = requests.get(
    "https://api.e-comms.dev/v1/email/01a0ba31-3fe4-7cc4-a1c6-64bdaaa5d99c",
    headers={"Authorization": "Bearer ek_live_<tu-clave>"},
)

body = response.json()
```

## Respuesta `200` — Encontrado

```json
{
  "id": "01a0ba31-3fe4-7cc4-a1c6-64bdaaa5d99c",
  "address": "ana@example.com",
  "status": "sent",
  "deliveryStatus": "delivered",
  "failureReason": null,
  "createdAt": "2026-09-19T12:00:00Z",
  "sentAt": "2026-09-19T12:00:01Z",
  "deliveredAt": "2026-09-19T12:00:04Z"
}
```

## Respuesta `404` — No encontrado

```json
{
  "code": "not_found",
  "message": "The message does not exist, or exists for another organization.",
  "details": null,
  "requestId": "01a0ba31-3fe4-7cc4-a1c6-64bdaaa5d99c"
}
```
