# Campañas API

> Crea campañas, elige sus listas de contactos y envíalas o prográmalas.

URL base: `https://api.emailit.com/v2`. Autentícate con `Authorization: Bearer <API key>`.

## Crear una campaña — POST /campaigns

> Crea una campaña de email en borrador con su remitente, su asunto y su cuerpo HTML o de texto, preparada para elegir sus listas de contactos y enviarla.

# Crear una campaña

Crea una campaña con estado `draft`. Requiere una clave de API con el permiso `full`. Emite un evento `campaign.created`.

Una campaña nueva no tiene destinatarios. Elige sus listas de contactos con [Actualizar una campaña](/es/docs/api-reference/campaigns/update/) y después [envíala o prográmala](/es/docs/api-reference/campaigns/send/). Los créditos se cobran cuando se envía la campaña: 2 créditos por email.

`POST /campaigns`

## Parámetros del cuerpo

- `name` (string, obligatorio): El nombre interno de la campaña. Los destinatarios no lo ven. Los demás endpoints de campañas aceptan el nombre en lugar del ID, así que, si los usas así, procura que los nombres sean únicos.

- `subject` (string): El asunto. Admite [etiquetas de combinación](/es/docs/campaigns/merge-tags/) como `{{first_name}}`.

- `from_email` (string): La dirección del remitente. Debe pertenecer a un dominio de envío verificado del espacio de trabajo, por ejemplo `news@acme.com`.

- `from_name` (string): El nombre visible del remitente, por ejemplo `Acme`. El mensaje se envía desde `Acme <news@acme.com>`.

- `reply_to` (string): La dirección de respuesta. Por defecto, `from_email` cuando se envía la campaña.

- `html` (string): El cuerpo HTML que envía Emailit. Admite las etiquetas de combinación `{{first_name}}`, `{{last_name}}`, `{{email}}`, `{{unsubscribe_url}}` y `{{cf.<key>}}` para los campos personalizados. Define el cuerpo al crear la campaña.

- `text` (string): El cuerpo en texto plano. Admite las mismas etiquetas de combinación que `html`.

- `preview_text` (string): El texto de vista previa que se guarda con la campaña. Emailit no lo inserta en el mensaje; si lo necesitas, añade un preheader oculto a `html`.

- `content` (string): El código fuente del cuerpo en el editor (por ejemplo, MJML), guardado tal cual. Emailit envía `html` y `text`, no `content`.

- `content_type` (string): El formato de `content`: `html`, `text` o `mjml`. Emailit no compila MJML; envía el HTML compilado en `html`.

## Devuelve

Devuelve `201 Created` con el objeto de campaña. `status` es `draft`. La respuesta no incluye `html`, `text` ni `content`.

Devuelve `400` si falta `name` y `403` si la clave de API no tiene el permiso `full`.

**Petición** `POST /campaigns`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "October newsletter",
    "subject": "October news for {{first_name}}",
    "from_email": "news@acme.com",
    "from_name": "Acme",
    "reply_to": "support@acme.com",
    "html": "<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href=\"{{unsubscribe_url}}\">Unsubscribe</a></p>",
    "text": "Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}"
  }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'October newsletter',
    subject: 'October news for {{first_name}}',
    from_email: 'news@acme.com',
    from_name: 'Acme',
    reply_to: 'support@acme.com',
    html: '<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>',
    text: 'Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}',
  }),
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={
        "name": "October newsletter",
        "subject": "October news for {{first_name}}",
        "from_email": "news@acme.com",
        "from_name": "Acme",
        "reply_to": "support@acme.com",
        "html": '<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>',
        "text": "Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}",
    },
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => [
        'name' => 'October newsletter',
        'subject' => 'October news for {{first_name}}',
        'from_email' => 'news@acme.com',
        'from_name' => 'Acme',
        'reply_to' => 'support@acme.com',
        'html' => '<p>Hi {{first_name}},</p><p>Here is what changed this month.</p><p><a href="{{unsubscribe_url}}">Unsubscribe</a></p>',
        'text' => 'Hi {{first_name}}, here is what changed this month. Unsubscribe: {{unsubscribe_url}}',
    ],
]);
$campaign = json_decode($response->getBody(), true);
```

**201**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "draft",
  "subject": "October news for {{first_name}}",
  "from_email": "news@acme.com",
  "from_name": "Acme",
  "reply_to": "support@acme.com",
  "preview_text": null,
  "content_type": "html",
  "created_at": "2026-10-01T09:30:12.482193Z",
  "updated_at": "2026-10-01T09:30:12.482193Z"
}
```

**400**

```json
{
  "error": "Bad Request"
}
```

**403**

```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Permission denied: campaigns:create"
}
```

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

## Obtener una campaña — GET /campaigns/{id}

> Obtén una campaña por su ID o su nombre, con su estado, su remitente, su programación y las listas de contactos a las que se dirige.

# Obtener una campaña

Obtiene una campaña por su ID o su nombre. Requiere una clave de API con el permiso `full`.

`GET /campaigns/{id}`

## Parámetros de ruta

- `id` (string, obligatorio): El ID (`cmp_…`) o el nombre de la campaña. Codifica para URL los nombres que contengan espacios o caracteres especiales.

## Devuelve

Devuelve el objeto de campaña.

- `object` (string): Siempre `campaign`.

- `id` (string): El ID de la campaña, con el prefijo `cmp_`.

- `status` (string): `draft`, `scheduled`, `queued`, `sending`, `sent`, `canceled` o `archived`. `queued` significa que una campaña programada ha llegado a su hora de envío y espera a que la procese un worker.

- `name` (string): El nombre interno de la campaña.

- `subject` (string): El asunto, con las etiquetas de combinación sin resolver.

- `from_email` (string): La dirección del remitente. `""` hasta que se define.

- `from_name` (string): El nombre visible del remitente. `""` hasta que se define.

- `reply_to` (string): La dirección de respuesta. `""` significa que las respuestas van a `from_email`.

- `preview_text` (string | null): El texto de vista previa que se guarda con la campaña.

- `content_type` (string): La etiqueta de formato del código fuente del editor: `html`, `text` o `mjml` en las campañas creadas con la API.

- `scheduled_at` (string | null): Cuándo se envía una campaña programada, en UTC.

- `sent_at` (string | null): Cuándo empezó el envío.

- `recipients` (object[]): Las listas de contactos a las que se dirige la campaña. Cada elemento tiene `audience_id` (`aud_…`) y `exclude` (`true` para una lista excluida).

El cuerpo (`html`, `text` y `content`) no se incluye en la respuesta. Las estadísticas de interacción están disponibles en el panel, en **Email Marketing → Campaigns**.

Devuelve `404` si ninguna campaña del espacio de trabajo coincide con `id`.

**Petición** `GET /campaigns/{id}`

**cURL**

```bash
curl https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', {
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.get(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->get('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$campaign = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "scheduled",
  "subject": "October news for {{first_name}}",
  "from_email": "news@acme.com",
  "from_name": "Acme",
  "reply_to": "support@acme.com",
  "preview_text": null,
  "content_type": "html",
  "sent_at": null,
  "scheduled_at": "2026-10-08 09:00:00+00",
  "created_at": "2026-10-01 09:30:12.482193+00",
  "updated_at": "2026-10-01 10:02:47.118204+00",
  "recipients": [
    { "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV", "exclude": false },
    { "audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": true }
  ]
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

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

## Actualizar una campaña — POST /campaigns/{id}

> Cambia el nombre, el remitente, el asunto o el texto de vista previa de una campaña, y define las listas de contactos a las que se envía o que se excluyen.

# Actualizar una campaña

Actualiza los campos que pasas y deja los demás sin cambios. Úsalo para elegir las listas de contactos de la campaña antes de enviarla. Requiere una clave de API con el permiso `full`. Emite un evento `campaign.updated`.

Una campaña programada envía lo que esté guardado a su hora de envío, así que puedes seguir editándola después de programarla.

`POST /campaigns/{id}`

## Parámetros de ruta

- `id` (string, obligatorio): El ID (`cmp_…`) o el nombre de la campaña.

## Parámetros del cuerpo

- `name` (string): El nombre interno de la campaña.

- `subject` (string): El asunto. Admite [etiquetas de combinación](/es/docs/campaigns/merge-tags/).

- `from_email` (string): La dirección del remitente, de un dominio de envío verificado.

- `from_name` (string): El nombre visible del remitente.

- `reply_to` (string): La dirección de respuesta. Una cadena vacía significa que las respuestas van a `from_email`.

- `preview_text` (string): El texto de vista previa que se guarda con la campaña.

- `content` (string): El código fuente del cuerpo en el editor, guardado tal cual.

- `content_type` (string): El formato de `content`: `html`, `text` o `mjml`.

- `recipients` (object[]): Las listas de contactos a las que se dirige. Sustituye las listas actuales. Incluye al menos una lista con `exclude` en `false`. - `audience_id` (cadena, obligatorio): el ID de una lista de contactos (`aud_…`) de este espacio de trabajo. - `exclude` (booleano, por defecto `false`): `true` guarda la lista como exclusión. El panel resta las listas excluidas de su estimación de destinatarios, pero de momento el envío no aplica las exclusiones, así que quita también esos contactos de las listas incluidas. Los ID de lista duplicados se ignoran. Al enviar, Emailit envía un email a cada contacto suscrito de las listas incluidas una sola vez y omite los contactos dados de baja y las direcciones bloqueadas.

El cuerpo HTML y el de texto se definen al [crear la campaña](/es/docs/api-reference/campaigns/create/). Los campos desconocidos del cuerpo se ignoran.

## Devuelve

Devuelve el objeto de campaña actualizado, con `recipients`.

Devuelve `422` si `recipients` no tiene ninguna lista incluida o hace referencia a una lista de otro espacio de trabajo, y `404` si la campaña no existe.

**Petición** `POST /campaigns/{id}`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Your October update, {{first_name}}",
    "recipients": [
      { "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV" },
      { "audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": true }
    ]
  }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    subject: 'Your October update, {{first_name}}',
    recipients: [
      { audience_id: 'aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV' },
      { audience_id: 'aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9', exclude: true },
    ],
  }),
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={
        "subject": "Your October update, {{first_name}}",
        "recipients": [
            {"audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV"},
            {"audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": True},
        ],
    },
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => [
        'subject' => 'Your October update, {{first_name}}',
        'recipients' => [
            ['audience_id' => 'aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV'],
            ['audience_id' => 'aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9', 'exclude' => true],
        ],
    ],
]);
$campaign = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "draft",
  "subject": "Your October update, {{first_name}}",
  "from_email": "news@acme.com",
  "from_name": "Acme",
  "reply_to": "support@acme.com",
  "preview_text": null,
  "content_type": "html",
  "scheduled_at": null,
  "created_at": "2026-10-01 09:30:12.482193+00",
  "updated_at": "2026-10-01 10:02:47.118204+00",
  "recipients": [
    { "audience_id": "aud_3Cz7WJ9GpvD7P0PQez50xOmkZSV", "exclude": false },
    { "audience_id": "aud_3hRmYTSQ4ca6y9tbPI0IQPjVTL9", "exclude": true }
  ]
}
```

**422**

```json
{
  "message": "Validation failed.",
  "errors": {
    "recipients": ["One or more audiences are invalid."]
  }
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

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

## Listar campañas — GET /campaigns

> Lista las campañas de un espacio de trabajo, de la más reciente a la más antigua, con paginación por páginas, búsqueda y filtros por estado, nombre y fechas.

# Listar campañas

Devuelve las campañas del espacio de trabajo, de la más reciente a la más antigua. Requiere una clave de API con el permiso `full`.

`GET /campaigns`

## Parámetros de consulta

- `page` (integer): El número de página, empezando por 1.

- `limit` (integer): Las campañas por página, de 1 a 100.

- `search` (string): Una búsqueda sin distinguir mayúsculas y minúsculas en el nombre o el asunto de la campaña.

- `status` (string): Un filtro rápido por estado: `draft`, `scheduled`, `sending` (también incluye `queued`), `sent`, `canceled`, `archived` o `all`.

- `match`, `order`, `direction`: consulta [Filtrado](https://emailit.com/es/docs/api-reference/filtering/).

### Claves de filtro

Los filtros usan parámetros de consulta `key.condition=value`, por ejemplo `status.exact=sent` o `created_at.after=2026-09-01`. Para las condiciones de cada tipo, consulta [Filtrado y ordenación](/es/docs/api-reference/filtering/).

| Clave | Tipo | Notas |
| --- | --- | --- |
| `name` | string | |
| `subject` | string | |
| `status` | enum | `draft`, `scheduled`, `queued`, `sending`, `sent`, `archived` |
| `created_at` | date | |
| `sent_at` | date | |

Claves de orden para `order`: `name`, `subject`, `status`, `created_at`, `sent_at`.

## Devuelve

Devuelve una página de objetos de campaña sin `reply_to`, `preview_text`, `content_type` ni `recipients`. Para obtenerlos, usa [Obtener una campaña](/es/docs/api-reference/campaigns/get/).

- `data` (object[]): Las campañas de esta página.

- `total_records` (integer): El número de campañas que coinciden con la consulta.

- `next_page_url` (string | null): La ruta de la página siguiente, o `null` en la última página. Solo incluye `page` y `limit`, así que vuelve a añadir tu búsqueda y tus filtros cuando la sigas.

- `previous_page_url` (string | null): La ruta de la página anterior, o `null` en la primera página.

**Petición** `GET /campaigns`

**cURL**

```bash
curl -G https://api.emailit.com/v2/campaigns \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -d limit=20 \
  -d status=sent \
  -d order=sent_at \
  -d direction=desc
```

**Node.js**

```javascript
const params = new URLSearchParams({ limit: '20', status: 'sent', order: 'sent_at', direction: 'desc' });
const res = await fetch(`https://api.emailit.com/v2/campaigns?${params}`, {
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const { data, total_records } = await res.json();
```

**Python**

```python
import os, requests

r = requests.get(
    "https://api.emailit.com/v2/campaigns",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    params={"limit": 20, "status": "sent", "order": "sent_at", "direction": "desc"},
)
campaigns = r.json()["data"]
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->get('campaigns', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'query' => ['limit' => 20, 'status' => 'sent', 'order' => 'sent_at', 'direction' => 'desc'],
]);
$campaigns = json_decode($response->getBody(), true)['data'];
```

**200**

```json
{
  "data": [
    {
      "object": "campaign",
      "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
      "name": "October newsletter",
      "status": "sent",
      "subject": "Your October update, {{first_name}}",
      "from_email": "news@acme.com",
      "from_name": "Acme",
      "sent_at": "2026-10-08 09:00:04+00",
      "scheduled_at": "2026-10-08 09:00:00+00",
      "created_at": "2026-10-01 09:30:12.482193+00",
      "updated_at": "2026-10-08 09:00:31+00"
    }
  ],
  "total_records": 34,
  "next_page_url": "/v2/campaigns?page=2&limit=20",
  "previous_page_url": null
}
```

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

## Enviar o programar una campaña — POST /campaigns/{id}/send

> Envía una campaña a sus listas de contactos de inmediato o programa una campaña en borrador para una fecha y hora futuras.

# Enviar o programar una campaña

Envía la campaña ahora o la programa si pasas un `scheduled_at` futuro. Requiere una clave de API con el permiso `full` y un [espacio de trabajo verificado](/es/docs/workspaces/production-access/): los espacios de trabajo sin verificar no pueden enviar campañas y reciben `403`.

Antes de enviarla, comprueba que la campaña tiene un `from_email` de un dominio verificado, un asunto, un cuerpo `html` o `text` y al menos una lista de contactos incluida (se define con [Actualizar una campaña](/es/docs/api-reference/campaigns/update/)). Cada email cuesta 2 créditos.

`POST /campaigns/{id}/send`

## Parámetros de ruta

- `id` (string, obligatorio): El ID (`cmp_…`) o el nombre de la campaña.

## Parámetros del cuerpo

- `scheduled_at` (string): Cuándo enviarla. Acepta ISO 8601 (`2026-10-08T09:00:00Z`), una marca de tiempo Unix en segundos o lenguaje natural como `tomorrow at 9am` (interpretado en UTC). La hora debe ser futura y la campaña debe estar en `draft`. Omítelo para enviarla ahora. Para enviar antes de tiempo una campaña programada, llama a este endpoint sin `scheduled_at`.

## Devuelve

**Enviar ahora:** el estado cambia a `sending` y Emailit emite `campaign.sending`. Después, Emailit crea un email por destinatario: todos los contactos suscritos de las listas incluidas, sin direcciones duplicadas y sin los contactos dados de baja ni las direcciones bloqueadas. Cuando todos los destinatarios han pasado al proceso de envío, el estado cambia a `sent` y Emailit emite `campaign.sent`. Sigue la entrega en el panel o con los [eventos de email](/es/docs/webhooks/event-types/).

**Programar:** el estado cambia a `scheduled` y Emailit emite `campaign.scheduled`. A la hora programada, la campaña pasa a `queued` (`campaign.queued`) y después se envía como se describe arriba.

La respuesta contiene `object`, `id`, `name` y el nuevo `status`, además de `scheduled_at` si la programas.

| Código | Cuándo |
| --- | --- |
| `403` | El espacio de trabajo no está verificado o la clave de API no tiene el permiso `full`. |
| `404` | Ninguna campaña coincide con `id`. |
| `422` | `scheduled_at` no se puede interpretar o no es una hora futura, o intentaste programar una campaña que no es un borrador. |

**Petición** `POST /campaigns/{id}/send`

**cURL**

```bash
curl -X POST https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scheduled_at": "2026-10-08T09:00:00Z" }'
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.EMAILIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ scheduled_at: '2026-10-08T09:00:00Z' }),
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
    json={"scheduled_at": "2026-10-08T09:00:00Z"},
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/send', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
    'json' => ['scheduled_at' => '2026-10-08T09:00:00Z'],
]);
$campaign = json_decode($response->getBody(), true);
```

**200 scheduled**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "scheduled",
  "scheduled_at": "2026-10-08T09:00:00.000000Z"
}
```

**200 sending**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "sending"
}
```

**403**

```json
{
  "code": "unverified_workspace_recipient",
  "error": "Workspace not verified",
  "message": "Unverified workspaces cannot send campaigns. You can send individual emails only to workspace members' account emails."
}
```

**422**

```json
{
  "error": "Campaign cannot be scheduled",
  "message": "Campaign status is 'sent'. Only draft campaigns can be scheduled."
}
```

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

## Cancelar una campaña — POST /campaigns/{id}/cancel

> Cancela una campaña en borrador o en pleno envío. Los emails que ya están en cola para su entrega no se recuperan.

# Cancelar una campaña

Cambia el estado de la campaña a `canceled` y emite un evento `campaign.canceled`. Requiere una clave de API con el permiso `full`.

Solo se pueden cancelar las campañas con estado `draft` o `sending`; cualquier otro estado devuelve `422`. Si cancelas una campaña que se está enviando, los emails que ya están en cola para su entrega no se recuperan.

`POST /campaigns/{id}/cancel`

## Parámetros de ruta

- `id` (string, obligatorio): El ID (`cmp_…`) o el nombre de la campaña.

## Devuelve

Devuelve `object`, `id`, `name` y `status` (`canceled`).

Devuelve `422` si el estado de la campaña no es `draft` ni `sending`, y `404` si la campaña no existe.

**Petición** `POST /campaigns/{id}/cancel`

**cURL**

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

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const campaign = await res.json();
```

**Python**

```python
import os, requests

r = requests.post(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
campaign = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->post('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN/cancel', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$campaign = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "status": "canceled"
}
```

**422**

```json
{
  "error": "Campaign cannot be canceled",
  "message": "Campaign status is 'scheduled'. Only 'draft' or 'sending' campaigns can be canceled."
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

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

## Eliminar una campaña — DELETE /campaigns/{id}

> Elimina de forma permanente una campaña por su ID o su nombre. Emite un evento campaign.deleted; los emails ya enviados no se ven afectados.

# Eliminar una campaña

Elimina una campaña de forma permanente. Requiere una clave de API con el permiso `full`. Emite un evento `campaign.deleted`.

Eliminar una campaña no afecta a los emails que ya se enviaron o se pusieron en cola. Para detener una campaña que se está enviando, primero [cancélala](/es/docs/api-reference/campaigns/cancel/).

`DELETE /campaigns/{id}`

## Parámetros de ruta

- `id` (string, obligatorio): El ID (`cmp_…`) o el nombre de la campaña.

## Devuelve

Devuelve `object`, `id`, `name` y `deleted: true`. Devuelve `404` si la campaña no existe.

**Petición** `DELETE /campaigns/{id}`

**cURL**

```bash
curl -X DELETE https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN \
  -H "Authorization: Bearer $EMAILIT_API_KEY"
```

**Node.js**

```javascript
const res = await fetch('https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
const result = await res.json();
```

**Python**

```python
import os, requests

r = requests.delete(
    "https://api.emailit.com/v2/campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
    headers={"Authorization": f"Bearer {os.environ['EMAILIT_API_KEY']}"},
)
result = r.json()
```

**PHP**

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.emailit.com/v2/']);

$response = $client->delete('campaigns/cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('EMAILIT_API_KEY')],
]);
$result = json_decode($response->getBody(), true);
```

**200**

```json
{
  "object": "campaign",
  "id": "cmp_3zNrBaNjAoPK1l0IL2GQ3pDkubN",
  "name": "October newsletter",
  "deleted": true
}
```

**404**

```json
{
  "error": "Campaign not found"
}
```

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