# Understanding alias options

> Learn about attachment processing and envelope data options for email aliases

Source: https://emailconnect.eu/help/alias-options-explained/

When creating or editing an alias in EmailConnect, you'll find two important options that control how email data is processed and delivered to your webhooks.

## Process attachments

This option determines how EmailConnect handles file attachments in incoming emails.

### Option 1: Inline (default)

When set to "Inline", attachments are:
- Converted to Base64 encoding
- Included directly in the webhook JSON payload
- Immediately available for processing

**Example payload with inline attachment:**
```json
{
  "message": {
    "subject": "Invoice for March",
    "attachments": [
      {
        "filename": "invoice-march.pdf",
        "contentType": "application/pdf",
        "size": 125840,
        "storage": "inline",
        "status": "included",
        "content": "JVBERi0xLjQKJeHp69MKMSAwIG9iago8PC9Ue..."
      }
    ]
  }
}
```

**Size limits for inlining:**
- **Paid plans**: files up to **2 MB** are inlined as Base64 in the payload.

  Two separate limits are at work here, and it's worth understanding both. **Settings → Storage** has a *maximum attachment size* slider (default **10 MB**, range 0.1–10 MB) — that is an **acceptance** limit, applied per account: anything larger is **rejected**, not offloaded. Separately, a fixed **2 MB** boundary decides inline-vs-S3 for the files we *do* accept.

  So on default settings a 1.5 MB PDF is inlined and a 5 MB PDF is offloaded to S3. **If you lower that slider below 2 MB, files over your limit are dropped, not offloaded.**
- **Free plan**: files up to **128 KB** are inlined. Free plans have no storage connection, so anything larger is **rejected outright** — it is never offloaded to S3.
- Non-inlineable file types (`.zip`, audio, video) are **never** inlined, even a 40 KB one. They go to storage on paid plans, and are rejected on Free.
- Any email whose raw size exceeds **10 MB** is rejected at the door, on every plan.

**Best for:**
- Small attachments (up to 2 MB on paid plans, 128 KB on Free)
- When you need immediate access to file contents
- Simple architectures without external storage
- Quick prototypes and MVPs

### Option 2: Managed S3 storage

When set to "Managed S3 storage", larger attachments are:
- Uploaded to S3-compatible object storage in the EU
- Delivered as a `downloadUrl` instead of Base64 content
- Fetched on demand, over HTTPS

**Example payload with Managed S3 storage:**
```json
{
  "message": {
    "subject": "Invoice for March",
    "attachments": [
      {
        "filename": "invoice-march.pdf",
        "contentType": "application/pdf",
        "size": 3145728,
        "storage": "s3",
        "status": "completed",
        "uploadType": "sync",
        "downloadUrl": "https://app.emailconnect.eu/attachments/9f8e7d6c5b4a3f2e/download"
      }
    ]
  }
}
```

**How `downloadUrl` works:** it points at **EmailConnect**, not at the storage bucket. When you fetch it we redirect (302) to a short-lived signed URL minted at that moment. This is deliberate — routing downloads through us means they can be counted, revoked, and kept in-region. There is no fixed URL expiry to plan around: the link keeps working for **as long as your retention window**, and stops working when that window ends. Fetch the file and store it on your side; do not hand the link on to users or embed it in a page.

**What actually goes to storage:**
- Files between roughly **2 MB and 10 MB** on paid plans (anything larger than the inline cap, up to the 10 MB email limit).
- **Any non-inlineable type at any size** — `.zip`, audio, video — even if it is only a few kilobytes.
- Nothing over 10 MB, ever: the whole email is rejected before it gets that far, so there is no "use S3 for big files" escape hatch.
- Not available on Free, which has no storage connection.

**Best for:**
- Attachments above the inline cap, and archive/media file types
- High-volume email processing
- When webhooks have payload size limits
- Long-term file storage needs

### Option 3: Custom S3 storage

Configure your own S3-compatible bucket for attachment storage:
- Full control over file retention
- Keep files in your own infrastructure
- Custom access policies
- Cost optimization for high volumes

**Configuration required:**
- Bucket name and region
- Access key and secret key
- Optional: custom endpoint for S3-compatible services (MinIO, Backblaze B2, etc.)

## Email content format

This option controls which email body formats are included in your webhook payload.

### Option 1: Both HTML and text (default)

When set to "Both", your webhook receives:
- `message.content.html`: The HTML version of the email body
- `message.content.text`: The plain text version of the email body

**Example payload:**
```json
{
  "message": {
    "subject": "Welcome to our service",
    "content": {
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
      "text": "Welcome!\n\nThanks for signing up."
    }
  }
}
```

(The body fields live under `message.content`, not at the top level.)

**Best for:**
- Applications that need to display emails in different contexts
- When you want fallback options for rendering
- Maximum flexibility in processing

### Option 2: HTML only

When set to "HTML only", your webhook receives only the `message.content.html` field.

**Best for:**
- Applications that only render HTML content
- When you want to reduce payload size
- Web-based email viewers

### Option 3: Text only

When set to "Text only", your webhook receives only the `message.content.text` field.

**Best for:**
- Text processing and analysis
- Logging and archival systems
- When HTML formatting isn't needed
- Simpler parsing requirements

## Extracted links

Every email is scanned for URLs, in both the HTML and the plain-text body, and the result is delivered as an array at `message.content.links`. It saves you parsing the body yourself. A URL taken from the HTML is delivered decoded (`&amp;` in the markup arrives as `&`), so it can be requested as it is, and a link that appears in both the HTML and the text body is listed once.

**On by default.** Switch off **Extracted links** on an alias to leave the array out.

The reason to switch it off is payload size. The links are already in the body; the array repeats them in structured form. On link-heavy mail such as newsletters that can be a noticeable share of the payload, so if your endpoint has a request-size limit and you do not use the array, turning it off is the cheapest way to shrink what we send. The bodies themselves are unaffected.

Available on all plans. What each link entry contains still depends on your plan: Free gets the URL and its domain, Maker and above also get the anchor text and where in the message the link was found.

## Include envelope data

This option adds technical email routing information to your webhook payload.

### What is envelope data?

The `envelope` object carries the technical facts about the message that sit outside the visible body — the routing headers, the bounce address, every recipient, and what EmailConnect did with it.

### When enabled

The `envelope` block is delivered in full:
```json
{
  "envelope": {
    "messageId": "<abc123@example.com>",
    "xMailer": null,
    "xOriginalTo": "invoices+acme@yourdomain.com",
    "returnPath": "bounces@shop.com",
    "allRecipients": {
      "to": ["invoices+acme@yourdomain.com"],
      "cc": [],
      "bcc": []
    },
    "headers": {
      "from": "orders@shop.com",
      "subject": "Order confirmation"
    },
    "processed": {
      "timestamp": "2026-07-13T10:30:01.000Z",
      "domain": "yourdomain.com",
      "alias": "invoices+acme@yourdomain.com",
      "originalSize": 248320
    }
  }
}
```

| Field | What it is |
|---|---|
| `messageId` | RFC 5322 Message-ID, as the sender set it. The same on every redelivery, but chosen by the sender, so it can repeat across different emails. To deduplicate, use the `webhook-id` header or the top-level `id` instead. |
| `xMailer` | The sending client, when it identified itself. `null` otherwise. |
| `xOriginalTo` | The `X-Original-To` header of the message, when it has one. `null` otherwise. |
| `returnPath` | The bounce address (the SMTP envelope sender). |
| `allRecipients` | `{ to, cc, bcc }` — the addresses on the `To:`, `Cc:` and `Bcc:` header lines. An address that got the mail only as Bcc is not listed. The address we accepted the mail for is `message.recipient.email`. |
| `headers` | The message headers by lower-cased name, as our parser read them. Not the raw header text: some values arrive as JSON strings, and the `List-*` headers are folded into one `list` entry. `list-id`, `list-unsubscribe` and `list-post` are also present under their own names, with the header text as sent. |
| `processed` | `{ timestamp, domain, alias, originalSize }` — what EmailConnect did with it, and how big the raw message was in bytes. `alias` is the address we accepted the mail for, the same as `message.recipient.email`; `aliasId` identifies the alias that matched. |

### When disabled (the default)

"Include envelope" is **off** by default. With it off, the block is not removed entirely — it is **reduced to `messageId` only**:

```json
{
  "envelope": {
    "messageId": "<abc123@example.com>"
  }
}
```

So `envelope.messageId` is always there, whatever the setting. For deduplication, use the `webhook-id` header or the top-level `id` in the body: we assign that one, so it is unique per email. See [Deduplicating deliveries](https://emailconnect.eu/help/webhook-signing/#deduplicating-deliveries).

Note that the sender, recipient and subject live under `message` (as `message.sender`, `message.recipient` and `message.subject`) — there are no top-level `from`, `to` or `subject` keys in the payload, with or without envelope data.

### Why envelope data matters

**Email forwarding detection:**
- `xOriginalTo` shows the original recipient when mail has been forwarded
- `allRecipients` shows everyone the message went to, not just your alias

**Bounce handling:**
- `returnPath` is the address that receives bounce notifications
- It is often different from the visible "From" address
- Critical for email deliverability tracking

**Debugging and auditing:**
- `headers` gives you the raw headers to inspect (including SPF/DKIM/DMARC ones)
- `processed` tells you which alias matched, on which domain, and when

### When to enable envelope data

**Enable for:**
- Email analytics applications
- Bounce processing systems
- Security-focused applications
- When debugging delivery issues
- Multi-tenant applications needing routing info

**Skip for:**
- Simple email-to-webhook conversions
- When you only need message content
- Applications that don't process technical headers

## Common configurations

### Support ticket system
- **Process attachments**: Inline (customers attach screenshots)
- **Include envelope**: No (not needed for tickets)

### Document processing system
- **Process attachments**: Managed S3 storage (large PDFs)
- **Include envelope**: No (focus on content)

### Email analytics platform
- **Process attachments**: Managed S3 storage (preserve originals)
- **Include envelope**: Yes (track routing)

### Simple notification system
- **Process attachments**: Inline (if any)
- **Include envelope**: No (keep it simple)

## Performance considerations

### Inline attachments
- Increases webhook payload size
- May hit size limits on receiving endpoints
- Faster for small files
- No additional API calls needed

### Managed S3 storage
- Keeps webhook payloads small
- Requires additional HTTP requests to fetch files
- Better for large files
- Adds slight processing delay

### Envelope data
- Minimal impact on payload size
- No performance impact
- Useful debugging information
- Can be ignored if not needed

Choose the configuration that best matches your use case and architectural requirements.
