# Adjuntos

> Adjunta archivos a los emails de la API como contenido base64 o desde una URL, inserta imágenes en línea con Content-ID y respeta los tipos de archivo permitidos y los límites de tamaño.

Esta página muestra cómo adjuntar archivos a los emails que envías con `POST /emails`, ya sea como contenido codificado en base64 o dejando que Emailit los descargue desde una URL. También trata las imágenes en línea, los tipos de archivo permitidos y los límites de tamaño.

## Campos de los adjuntos

Pasa un array `attachments`. Cada elemento es un objeto con estos campos:

- `filename` (string, obligatorio): El nombre de archivo que ve el destinatario. Debe terminar en una [extensión permitida](#allowed-file-types).
- `content` (string): El archivo codificado en base64. Usa `content` o `url`, no ambos.
- `url` (string): Una URL `http://` o `https://` desde la que Emailit descarga el archivo. Usa `content` o `url`, no ambos.
- `content_type` (string): El tipo MIME, como `application/pdf`. Obligatorio con `content`. Con `url`, por defecto se usa el `Content-Type` que devuelve el servidor.
- `content_id` (string): Un Content-ID. Si lo defines, el adjunto pasa a ser en línea y tu HTML puede mostrarlo con `cid:`.
- `encoding` (string): Cómo está codificado `content`. Déjalo en `base64` salvo que tengas un motivo para cambiarlo.

## Adjuntar un archivo en base64

Lee el archivo, codifícalo en base64 y envíalo con su tipo MIME.

**cURL**

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"from\": \"Acme Billing <billing@acme.com>\",
    \"to\": \"ada@example.com\",
    \"subject\": \"Invoice INV-1042\",
    \"text\": \"Your invoice is attached.\",
    \"attachments\": [{
      \"filename\": \"INV-1042.pdf\",
      \"content\": \"$(base64 < INV-1042.pdf | tr -d '\n')\",
      \"content_type\": \"application/pdf\"
    }]
  }"
```

**Node.js**

```javascript
import { readFile } from 'node:fs/promises';
import { Emailit } from '@emailit/node';

const emailit = new Emailit(process.env.EMAILIT_API_KEY);
const pdf = await readFile('INV-1042.pdf');

await emailit.emails.send({
  from: 'Acme Billing <billing@acme.com>',
  to: 'ada@example.com',
  subject: 'Invoice INV-1042',
  text: 'Your invoice is attached.',
  attachments: [
    {
      filename: 'INV-1042.pdf',
      content: pdf.toString('base64'),
      content_type: 'application/pdf',
    },
  ],
});
```

**Python**

```python
import base64
import os
from emailit import EmailitClient

client = EmailitClient(os.environ["EMAILIT_API_KEY"])

with open("INV-1042.pdf", "rb") as f:
    pdf = base64.b64encode(f.read()).decode("ascii")

client.emails.send({
    "from": "Acme Billing <billing@acme.com>",
    "to": "ada@example.com",
    "subject": "Invoice INV-1042",
    "text": "Your invoice is attached.",
    "attachments": [{
        "filename": "INV-1042.pdf",
        "content": pdf,
        "content_type": "application/pdf",
    }],
})
```

**PHP**

```php
$emailit = Emailit::client(getenv('EMAILIT_API_KEY'));

$emailit->emails()->send([
    'from' => 'Acme Billing <billing@acme.com>',
    'to' => 'ada@example.com',
    'subject' => 'Invoice INV-1042',
    'text' => 'Your invoice is attached.',
    'attachments' => [[
        'filename' => 'INV-1042.pdf',
        'content' => base64_encode(file_get_contents('INV-1042.pdf')),
        'content_type' => 'application/pdf',
    ]],
]);
```

## Adjuntar un archivo desde una URL

En lugar de codificar tú el archivo, dale a Emailit una `url`. Emailit descarga el archivo mientras construye el mensaje, así que la petición tarda lo mismo que la descarga.

```json
{
  "from": "Acme Billing <billing@acme.com>",
  "to": "ada@example.com",
  "subject": "Invoice INV-1042",
  "text": "Your invoice is attached.",
  "attachments": [
    {
      "filename": "INV-1042.pdf",
      "url": "https://files.acme.com/invoices/INV-1042.pdf"
    }
  ]
}
```

La URL tiene que cumplir estas reglas; si no, la petición falla con `422` y `Attachment error`:

- Usa `http` o `https` y apunta a un host público. Las direcciones privadas e internas se rechazan.
- Devuelve el archivo directamente con un estado `2xx`. No se siguen las redirecciones.
- La descarga termina en 30 segundos como máximo.
- El archivo no ocupa más de 25 MB, según su cabecera `Content-Length`.

Emailit construye una copia distinta del mensaje para cada destinatario y descarga los adjuntos por URL para cada copia. Asegúrate de que las URL firmadas o con caducidad sigan siendo válidas durante toda la petición, y de que el servidor de archivos pueda soportar una descarga por destinatario.

## Insertar imágenes en línea

Para mostrar una imagen dentro del cuerpo HTML en lugar de como un adjunto aparte, dale un `content_id` y haz referencia a ese ID con `cid:` en una etiqueta `img`.

```json
{
  "from": "Acme <hello@acme.com>",
  "to": "ada@example.com",
  "subject": "Your weekly report",
  "html": "<p><img src=\"cid:chart-week-40\" alt=\"Weekly signups\" width=\"600\"></p>",
  "attachments": [
    {
      "filename": "chart.png",
      "content": "iVBORw0KGgoAAAANSUhEUgAA...",
      "content_type": "image/png",
      "content_id": "chart-week-40"
    }
  ]
}
```

El `content_id` del adjunto y el valor que sigue a `cid:` deben coincidir exactamente. Las imágenes en línea hacen más grande el mensaje para cada destinatario, así que para los logotipos y otras imágenes compartidas suele ser mejor opción una URL de imagen alojada en el HTML.

## Límites de tamaño

| Límite | Valor |
| --- | --- |
| Mensaje completo, tras la codificación | 40 MB. Los mensajes más grandes fallan con `413 Message too large`. |
| Un adjunto descargado desde `url` | 25 MB |
| Tiempo de espera de la descarga desde `url` | 30 s |
| Cuerpo JSON de la petición | 50 MB |

La codificación base64 hace que los archivos ocupen aproximadamente un tercio más, y el límite de 40 MB se aplica al mensaje codificado. En la práctica, mantén el tamaño total de tus archivos por debajo de unos 29 MB. Para cualquier cosa más grande, sube el archivo a tu propio almacenamiento y envía un enlace.

## Tipos de archivo permitidos

`filename` debe terminar en una de estas extensiones. Cualquier otra extensión, o un nombre sin extensión, no supera la validación y devuelve `400`.

| Categoría | Extensiones |
| --- | --- |
| Texto | `.txt`, `.csv`, `.log`, `.css`, `.ics`, `.xml` |
| Imágenes | `.jpg`, `.jpe`, `.jpeg`, `.gif`, `.png`, `.bmp`, `.psd`, `.tif`, `.tiff`, `.svg`, `.indd`, `.ai`, `.eps` |
| Documentos | `.doc`, `.docx`, `.rtf`, `.odt`, `.ott`, `.pdf`, `.pub`, `.pages`, `.mobi`, `.epub` |
| Audio | `.mp3`, `.m4a`, `.m4v`, `.wma`, `.ogg`, `.flac`, `.wav`, `.aif`, `.aifc`, `.aiff` |
| Vídeo | `.mp4`, `.mov`, `.avi`, `.mkv`, `.mpeg`, `.mpg`, `.wmv` |
| Hojas de cálculo | `.xls`, `.xlsx`, `.ods`, `.numbers` |
| Presentaciones | `.odp`, `.ppt`, `.pptx`, `.pps`, `.key` |
| Archivos comprimidos y contactos | `.zip`, `.vcf` |
| Email | `.eml` |
| Firmas y cifrado | `.p7c`, `.p7m`, `.p7s`, `.pgp`, `.asc`, `.sig` |

Los archivos ejecutables y los scripts no están en la lista y no se pueden adjuntar.

## Leer los adjuntos de un email enviado

[Listar adjuntos](/es/docs/api-reference/emails/attachments/) (`GET /emails/{id}/attachments`) devuelve cada adjunto con su `filename`, `content_type`, `size`, `content_id`, `content_disposition` (`attachment` o `inline`) y su `content` en base64. Necesita una clave **Full Access**. Los adjuntos se eliminan junto con el contenido del mensaje cuando termina tu periodo de [retención de datos](/es/docs/data-retention/).

## Solución de problemas

| Error | Qué comprobar |
| --- | --- |
| `Attachment at index 0 missing content_type (required when using 'content')` | Añade `content_type` a cada adjunto en base64. |
| `Attachment 'report.exe' has unsupported file type '.exe'` | Usa una extensión permitida, o mete el archivo en un `.zip`. |
| `Attachment at index 0 cannot have both 'content' and 'url'` | Envía solo uno de los dos. |
| `Attachment error` con `Failed to fetch attachment` | La URL ha devuelto un estado de error, ha redirigido, ha agotado el tiempo de espera o no es pública. Ábrela desde un servidor fuera de tu red para comprobarlo. |
| `Attachment error` con `Attachment too large (max 25MB)` | Aloja el archivo y envía un enlace en su lugar. |
| `413 Message too large` | Reduce el tamaño total de los adjuntos. |

## Ver también

- [Enviar un email](/es/docs/email-api/send-email/)
- Referencia de la API: [Enviar un email](/es/docs/api-reference/emails/send/)
- [Retención de datos](/es/docs/data-retention/)

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