# Programar y cancelar emails

> Envía un email más tarde con scheduled_at, cambia la hora de envío o cancela un email programado, aceptado o en reintento con la API o desde el panel.

Esta página explica cómo programar un email para más tarde con la API de email, cómo pasarlo a otra hora y cómo cancelar un email antes de que salga. La cancelación también funciona con emails que no estaban programados, siempre que todavía no se hayan entregado.

## Programar un email

Añade `scheduled_at` a una [petición de envío](/es/docs/email-api/send-email/). La respuesta tiene `"status": "scheduled"` y la hora normalizada en `scheduled_at`, y el email de cada destinatario emite [`email.scheduled`](/es/docs/webhooks/events/email/scheduled/) en lugar de `email.accepted`.

`scheduled_at` acepta estos formatos:

| Formato | Ejemplo | Notas |
| --- | --- | --- |
| ISO 8601 con zona horaria | `2026-10-05T09:00:00Z`, `2026-10-05T09:00:00+02:00` | Recomendado. Incluye siempre `Z` o un desplazamiento. |
| Lenguaje natural | `tomorrow at 9am`, `in 2 hours`, `next monday 10:00`, `friday 5pm` | Se interpreta en UTC, así que `tomorrow at 9am` significa las 09:00 UTC. |

Una hora que es la actual o que ya ha pasado envía el email de inmediato con el estado `accepted`.

> **Comprueba el estado de la respuesta:** Si Emailit no puede leer el valor de `scheduled_at`, no rechaza la petición: el email se envía al momento. Comprueba que la respuesta tiene `"status": "scheduled"` y el `scheduled_at` que esperabas. Las marcas de tiempo Unix no se reconocen; conviértelas antes a ISO 8601.

**cURL**

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <reminders@acme.com>",
    "to": "ada@example.com",
    "subject": "Your appointment is tomorrow",
    "text": "See you at 14:00.",
    "scheduled_at": "2026-10-05T09:00:00Z"
  }'
```

**Node.js**

```javascript
const email = await emailit.emails.send({
  from: 'Acme <reminders@acme.com>',
  to: 'ada@example.com',
  subject: 'Your appointment is tomorrow',
  text: 'See you at 14:00.',
  scheduled_at: '2026-10-05T09:00:00Z',
});
```

**Python**

```python
email = client.emails.send({
    "from": "Acme <reminders@acme.com>",
    "to": "ada@example.com",
    "subject": "Your appointment is tomorrow",
    "text": "See you at 14:00.",
    "scheduled_at": "2026-10-05T09:00:00Z",
})
```

**PHP**

```php
$email = $emailit->emails()->send([
    'from' => 'Acme <reminders@acme.com>',
    'to' => 'ada@example.com',
    'subject' => 'Your appointment is tomorrow',
    'text' => 'See you at 14:00.',
    'scheduled_at' => '2026-10-05T09:00:00Z',
]);
```

Emailit prepara un email programado cuando haces la petición, no a la hora de envío. La plantilla se renderiza, los adjuntos por URL se descargan y los créditos se cobran por adelantado. Para cambiar el contenido, cancela el email y envía uno nuevo.

## Cambiar la hora de envío

Usa [Actualizar un email programado](/es/docs/api-reference/emails/update/) (`POST /emails/{id}`) con un `scheduled_at` nuevo. Se aceptan los mismos formatos.

- El estado del email debe ser `scheduled`.
- Deben faltar más de 3 minutos para su hora de envío actual.
- La nueva hora de envío debe estar más de 3 minutos en el futuro.

**cURL**

```bash
curl https://api.emailit.com/v2/emails/em_33VtK8mRq1xZp7LwN4cY2bHsDfa \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scheduled_at": "2026-10-05T15:00:00Z" }'
```

**Node.js**

```javascript
await emailit.emails.update('em_33VtK8mRq1xZp7LwN4cY2bHsDfa', {
  scheduled_at: '2026-10-05T15:00:00Z',
});
```

**Python**

```python
client.emails.update("em_33VtK8mRq1xZp7LwN4cY2bHsDfa", {
    "scheduled_at": "2026-10-05T15:00:00Z",
})
```

**PHP**

```php
$emailit->emails()->update('em_33VtK8mRq1xZp7LwN4cY2bHsDfa', [
    'scheduled_at' => '2026-10-05T15:00:00Z',
]);
```

```json
{
  "object": "email",
  "id": "em_33VtK8mRq1xZp7LwN4cY2bHsDfa",
  "status": "scheduled",
  "scheduled_at": "2026-10-05T15:00:00.000Z",
  "updated_at": "2026-10-01T10:02:44.193027Z",
  "message": "Email schedule has been updated successfully"
}
```

A diferencia de un envío nuevo, aquí una hora que no se puede leer se rechaza con `422 Invalid scheduled_at`. Una petición que incumple la regla de los 3 minutos, o que se dirige a un email que no está programado, falla con `422 Cannot update email`. Una petición con varios destinatarios crea un email por destinatario, así que reprograma cada ID `em_` del mapa `ids`. La reprogramación no está disponible en el panel.

## Cancelar un email

Puedes cancelar un email saliente mientras tenga uno de estos estados:

| Estado | ¿Se puede cancelar? | Notas |
| --- | --- | --- |
| `scheduled` | Sí | Solo mientras falten más de 3 minutos para la hora de envío. |
| `accepted` | Sí, sin garantía | El email está esperando en la cola de envío o a punto de salir de ella. |
| `attempted` | Sí, sin garantía | Un intento de entrega ha fallado temporalmente. La cancelación detiene los reintentos restantes. |
| Cualquier otro estado | No | Los emails entregados, rebotados, fallidos, rechazados, bloqueados, retenidos o ya cancelados no se pueden cancelar. |

**Panel**

  1. Ve a **Email API → Emails**.
  2. Selecciona **Cancel delivery** en la fila del email, o abre el email y selecciona **Cancel delivery** en la parte superior de la página.
  3. Confirma. Si ya había empezado un intento de entrega, el panel te avisa de que el intento puede completarse igualmente y de que se han detenido los reintentos restantes.

**API**

  Llama a [Cancelar un email](/es/docs/api-reference/emails/cancel/) (`POST /emails/{id}/cancel`). Funciona con claves **Full Access** y **Sending Only**.

```bash
curl -X POST https://api.emailit.com/v2/emails/em_33VtK8mRq1xZp7LwN4cY2bHsDfa/cancel \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

```json
{
  "object": "email",
  "id": "em_33VtK8mRq1xZp7LwN4cY2bHsDfa",
  "status": "canceled",
  "in_flight": false,
  "message": "Email has been canceled and removed from the send queue."
}
```

Cuando `in_flight` es `true`, el email se ha cancelado, pero puede que ya haya un intento de entrega en curso, y el mensaje dice «The current delivery attempt may still complete; remaining retries were stopped.» Un estado que no se puede cancelar, o un email programado a menos de 3 minutos de su hora de envío, devuelve `422 Cannot cancel email`.

La cancelación no reembolsa los créditos cobrados cuando el email se envió con la API.

### Cómo funciona la cancelación

La cancelación saca el email de la cola de envío. No lo retira de la bandeja de entrada del destinatario.

1. Emailit comprueba que el email todavía se puede cancelar.
2. Cambia el estado a `canceled`, añade una entrada «Canceled» al historial de entregas del email y lo saca de la cola de envío.
3. Si un proceso de entrega ya ha recogido el email, ese proceso vuelve a comprobar el estado justo antes de pasar el mensaje al servidor del destinatario y lo omite si ve `canceled`.
4. Emailit emite `email.canceled` con el `previous_status`.

Si el mensaje ya iba de camino al servidor del destinatario, ese intento puede tener éxito igualmente. Emailit mantiene el estado `canceled` aunque ese intento simultáneo se entregue o rebote, pero el destinatario puede recibir el mensaje de todos modos. Entiende la cancelación como «detener esto antes de que salga», no como «anular el envío».

## Estados y eventos

| Momento | Estado | Evento de webhook |
| --- | --- | --- |
| Petición con un `scheduled_at` futuro | `scheduled` | [`email.scheduled`](/es/docs/webhooks/events/email/scheduled/) |
| Llega la hora de envío | `delivered`, `attempted`, `bounced`, etc. | El evento de entrega correspondiente, como [`email.delivered`](/es/docs/webhooks/events/email/delivered/) |
| Cancelado | `canceled` | `email.canceled`, con `status` y `previous_status` |

Un email programado no emite `email.accepted` cuando llega su hora de envío. Para la lista completa, consulta [Estados de los emails](/es/docs/logs/email-statuses/).

## Ver también

- [Actualizar un email programado](/es/docs/api-reference/emails/update/)
- [Cancelar un email](/es/docs/api-reference/emails/cancel/)
- [Enviar un email](/es/docs/email-api/send-email/)
- [Estados de los emails](/es/docs/logs/email-statuses/)
- [¿Por qué mi email se queda en Accepted o Scheduled?](/es/docs/kb/email-stuck-in-scheduled-or-accepted/)

---
Fuente: https://emailit.com/es/docs/email-api/scheduling/
