# Enviar correo transaccional (/es/api-reference/public-api/sendEmail)

`POST /v1/send`

Base URL: `https://api.bitelio.com`

Envía un correo transaccional mediante la API pública. Crea o actualiza automáticamente el contacto destinatario.

**Contenido obligatorio:** un ID de `template`, **o bien** tanto `subject` como `body`. Los campos de la plantilla pueden sobrescribirse con campos explícitos en la solicitud.

**Remitente:** `from` es obligatorio salvo que uses una plantilla que ya tenga configurado un `from`. El dominio del remitente debe estar verificado.

**Varios destinatarios:** cuando `to` es un array, cada destinatario se procesa secuencialmente con su propio upsert de contacto y su propio correo renderizado — no existe semántica de envío por lotes. El envío siempre es inmediato; para envíos programados, usa una Campaña.

**Adjuntos:** hasta 10 adjuntos por correo y 10 MB en total de forma predeterminada. El tamaño total del mensaje no puede superar los 40 MB.

## Header parameters

- `Idempotency-Key`: string — Clave opcional que garantiza que esta solicitud se ejecute como máximo una vez. Si la clave ya fue usada por tu proyecto, la solicitud se rechaza con `409` en lugar de ejecutarse una segunda vez. Las claves están limitadas a tu proyecto, expiran a las 24 horas y deben tener entre 1 y 255 caracteres ASCII imprimibles.

## Request body

- `to`: string (email) | object | array<string (email) | object> (required) — Correo(s) del destinatario. Puede ser un string, un objeto con {name, email}, o un array de cualquiera de los dos.
- `subject`: string — Asunto del correo. Obligatorio si no se proporciona `template`. No puede contener saltos de línea.
- `body`: string — Cuerpo del correo (HTML). Obligatorio si no se proporciona `template`.
- `template`: string — ID de la plantilla a usar para este correo. Cuando se proporciona, usa el subject, body, from y reply-to configurados en la plantilla. Puedes sobrescribirlos proporcionando explícitamente los campos subject, body, from o reply en la solicitud. Las variables de la plantilla se completan a partir del campo data.
- `from`: string (email) | object — Dirección de correo del remitente (requiere un dominio verificado). Obligatorio salvo que uses una plantilla que ya tenga configurada una dirección 'from'. Puede ser un string (p. ej., 'hello@example.com') o un objeto con {name, email} (p. ej., {name: 'My App', email: 'hello@example.com'}).
- `name`: string — **Obsoleto.** Nombre para mostrar del remitente. Se prefiere `from: { name, email }`. Solo se usa como alternativa cuando `from` es un string y no se ha definido un nombre ahí.
- `subscribed`: boolean — Estado de suscripción a aplicar al destinatario. Para contactos **nuevos**, el valor por defecto en `/v1/send` es `false`. Para contactos **existentes**, omitir este campo conserva su estado actual — pasa `true` o `false` para cambiarlo explícitamente. Un cambio emite `contact.subscribed` o `contact.unsubscribed`.
- `data`: object — Variables para el renderizado de la plantilla y actualizaciones de datos del contacto. Cada valor puede ser: - Un valor primitivo (string, número, booleano) — se guarda en el contacto y queda disponible como variable de plantilla. - `null` — elimina el campo del contacto. - Un string vacío — se ignora (no sobrescribe datos existentes). - Un objeto `{ value, persistent: false }` — se usa solo para este envío, sin guardarse en el contacto (ideal para códigos de restablecimiento de contraseña o enlaces mágicos de un solo uso). Las claves reservadas (`id`, `bitelio_id`, `bitelio_email`, `email`, `unsubscribeUrl`, `subscribeUrl`, `manageUrl`) se filtran silenciosamente.
- `headers`: object — Encabezados de correo personalizados. Los nombres de encabezado no pueden contener `\r\n`. Los valores de encabezado están limitados a 998 caracteres y no pueden contener `\r\n` (se rechaza la inyección de encabezados).
- `reply`: string (email) — Dirección de respuesta (reply-to).
- `attachments`: array<object> — Adjuntos del correo. Límite predeterminado: 10 adjuntos y 10 MB en total. El tamaño completo del mensaje no puede superar los 40 MB.
  items:
    - `filename`: string (required) — Nombre de archivo del adjunto. No puede contener saltos de línea ni comillas.
    - `content`: string (required) — Contenido del archivo codificado en Base64.
    - `contentType`: string (required) — Tipo MIME (p. ej., `application/pdf`, `image/png`).
    - `contentId`: string — Content-ID para imágenes en línea. Obligatorio cuando `disposition` es `inline`. Referencia la imagen en el cuerpo del correo mediante `<img src="cid:yourContentId">`.
    - `disposition`: enum ("attachment" | "inline") — Usa `inline` junto con `contentId` para incrustar imágenes en el cuerpo. Usa `attachment` (el valor por defecto) para archivos descargables.

Example:

```json
{
  "to": "user@example.com"
}
```

## Responses

### `200` — Correo puesto en cola correctamente

- `success`: boolean
- `data`: object
  - `emails`: array<object>
    items:
      - `contact`: object
        - `id`: string
        - `email`: string
      - `email`: string — ID del registro de correo de Bitelio. Úsalo para correlacionar eventos de webhook (que incluyen este ID como 'emailId' en los datos del evento) con tus solicitudes de envío.
  - `timestamp`: string (date-time)

```json
{
  "success": false,
  "data": {
    "emails": [
      {
        "contact": {
          "id": "string",
          "email": "string"
        },
        "email": "string"
      }
    ],
    "timestamp": "2026-10-13T07:11:40.114Z"
  }
}
```

### `400` — Solicitud incorrecta

- `code`: integer
- `error`: string
- `message`: string
- `time`: integer

```json
{
  "code": 0,
  "error": "string",
  "message": "string",
  "time": 0
}
```

### `401` — No autorizado

- `code`: integer
- `error`: string
- `message`: string
- `time`: integer

```json
{
  "code": 0,
  "error": "string",
  "message": "string",
  "time": 0
}
```

### `409` — La Idempotency-Key ya fue usada. La solicitud fue rechazada, no ejecutada.

- `code`: integer
- `error`: string
- `message`: string
- `time`: integer

```json
{
  "code": 0,
  "error": "string",
  "message": "string",
  "time": 0
}
```

## Example request

```bash
curl -X POST 'https://api.bitelio.com/v1/send' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"to":"user@example.com"}'
```
