# Using email headers and MIME data

Source: https://developer.nylas.com/docs/v3/email/headers-mime-data/

The Nylas Email API allows you to work with message headers and MIME data.

## The message ID header

When you send a message using the Nylas Messages API, Nylas creates a unique `message_id_header` value for the SMTP transaction, similar to:

```text
4ottpfaje0kqx8iagoih0h3tp-0@mailer.nylas.com
```

This header is required by the provider's SMTP server and is part of the standard email protocol. It's visible only in the sender's database and isn't an object you can use or update through the API.

The provider's SMTP server may change this value during the sending process. Avoid using `message_id_header` values with the `@mailer.nylas.com` domain for email configuration, as the provider may overwrite them.

## What are email headers?

[Email headers](https://en.wikipedia.org/wiki/Email#Message_header) are a collection of key-value pairs that define important information about a message (the subject, its recipients, the time it was sent, and so on). Typically, they're included at the beginning of a message's raw data.

A message might include multiple headers with the same name (for example, multiple `Received` headers), or custom headers defined by the sender. Custom headers are generally prefixed with `X-` (for example, `X-Received`).

```txt
Delivered-To: nyla@example.com
Received: Thu, 21 Mar 2024 09:27:34 -0700 (PDT)
X-Received: Thu, 21 Mar 2024 09:27:33 -0700 (PDT)
Return-Path: <EMAIL_ADDRESS>
Received: Thu, 21 Mar 2024 09:27:33 -0700 (PDT)
Date: Thu, 21 Mar 2024 11:27:33 -0500 (CDT)
From: Team Nylas <tips@nylas.com>
Reply-To: tips@nylas.com
To: nyla@example.com
Message-ID: <MESSAGE_ID>
Subject: Upgrade to Nylas API v3, now generally available
...
```

## Using email headers

Nylas can return message headers on [Get Message](/docs/reference/api/messages/get-messages-id/), [Get all Messages](/docs/reference/api/messages/get-messages/), and [Send Message](/docs/reference/api/messages/send-message/) requests. Set the `fields` query parameter to control which headers Nylas returns:

- `fields=include_headers` returns the **full** header set on the message.
- `fields=include_basic_headers` returns **only the three RFC threading headers** — `Message-ID`, `In-Reply-To`, and `References`. Use this option when you only need to track message identity and thread relationships. The response payload is significantly smaller than `include_headers`.

Without either parameter, Nylas doesn't return the `headers` array.

### Provider support

`fields=include_basic_headers` is supported on all providers: Google, Microsoft, EAS, EWS, and IMAP.

`fields=include_headers` returns the full header set on Google, Microsoft, and EAS. On EWS and IMAP, it returns only the headers Nylas generates for MIME — provider limitations mean the full header set isn't reachable. If you need `Message-ID`, `In-Reply-To`, or `References` on those providers, use `include_basic_headers`.

### Get headers on Get Message and Get all Messages

When you set the `fields` query parameter on a [Get all Messages request](/docs/reference/api/messages/get-messages/), Nylas returns the matching `headers` array on each message in the list. You can also fetch a single message's headers directly with a [Get Message request](/docs/reference/api/messages/get-messages-id/).

```bash
curl --request GET \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/<MESSAGE_ID>/?fields=include_headers' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json'
```

```json {28-37} [headers-Response (JSON)]
{
  "request_id": "5fa64c92-e840-4357-86b9-2aa364d35b88",
  "data": {
    "grant_id": "<NYLAS_GRANT_ID>",
    "object": "message",
    "id": "<MESSAGE_ID>",
    "thread_id": "<THREAD_ID>",
    "date": 1635355739,
    "to": [
      {
        "name": "Leyah Miller",
        "email": "leyah@example.com"
      }
    ],
    "cc": [
      {
        "name": "Kaveh",
        "email": "kaveh@example.com"
      }
    ],
    "bcc": [],
    "from": [
      {
        "name": "Nyla",
        "email": "nyla@example.com"
      }
    ],
    "reply_to": [
      {
        "name": "Nyla",
        "email": "nyla@example.com"
      }
    ],
    "folders": ["INBOX"],
    "attachments": [],
    "headers": [
      {
        "name": "Delivered-To",
        "value": "leyah@example.com"
      },
      {
        "name": "Received",
        "value": "Thu, 21 Mar 2024 09:27:34 -0700 (PDT)"
      }
    ],
    "subject": "Reminder: Annual Philosophy Club Meeting",
    "body": "Don't forget, we're meeting on Thursday!",
    "snippet": "Don't forget, we're meeting on Thursday!",
    "starred": false,
    "unread": true
  }
}
```

To get only the threading headers, use `fields=include_basic_headers` instead. The response is identical except the `headers` array contains only `Message-ID`, `In-Reply-To`, and `References`:

```bash
curl --request GET \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/<MESSAGE_ID>/?fields=include_basic_headers' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>'
```

```json {4-15} [basicHeaders-Response (JSON, abbreviated)]
{
  "request_id": "5fa64c92-e840-4357-86b9-2aa364d35b88",
  "data": {
    "headers": [
      {
        "name": "Message-ID",
        "value": "<CAJ-xQ1KrM2x@mail.example.com>"
      },
      {
        "name": "In-Reply-To",
        "value": "<CAJ-xQ1KrM1x@mail.example.com>"
      },
      {
        "name": "References",
        "value": "<CAJ-xQ1KrM0x@mail.example.com> <CAJ-xQ1KrM1x@mail.example.com>"
      }
    ]
  }
}
```

### Get headers on Send Message

When you set the `fields` query parameter on a [Send Message request](/docs/reference/api/messages/send-message/), Nylas includes the message's `headers` array on the send response. This is useful when you need the `Message-ID` of a sent message — for example, to store it for later thread reconstruction, or to deduplicate inbound webhooks against messages your application sent.

> **Info:** 
> **Synchronous send only.** The `fields` parameter has no effect when you set the `send_at` field on the request. Scheduled (asynchronous) send doesn't return headers on the API response.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send?fields=include_basic_headers' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "to": [{"email": "leyah@example.com", "name": "Leyah Miller"}],
    "subject": "Reminder: Annual Philosophy Club Meeting",
    "body": "Don'\''t forget, we'\''re meeting on Thursday!"
  }'
```

```json {7-22} [send-Response (JSON, abbreviated)]
{
  "request_id": "5fa64c92-e840-4357-86b9-2aa364d35b88",
  "data": {
    "grant_id": "<NYLAS_GRANT_ID>",
    "object": "message",
    "id": "<MESSAGE_ID>",
    "headers": [
      {
        "name": "Message-ID",
        "value": "<CAJ-xQ1KrM2x@mail.example.com>"
      },
      {
        "name": "In-Reply-To",
        "value": ""
      },
      {
        "name": "References",
        "value": ""
      }
    ],
    "subject": "Reminder: Annual Philosophy Club Meeting",
    "thread_id": "<THREAD_ID>"
  }
}
```

### Working with header data

Nylas parses both the header name and content directly from the message, so any encoded headers are also encoded in the API response. If you expect to use any encoded header data, your project must be able to decode it.

Messages might contain multiple headers with the same name. Nylas doesn't merge or de-duplicate the list of headers. If you want to work with a specific header, Nylas recommends iterating through the `headers` array and selecting the one you want to use.

## What is MIME data?

Email providers use the [MIME format](https://en.wikipedia.org/wiki/MIME) to represent the raw data of a message as blocks of information. MIME data is generally preceded by the `MIME-Version` header and the `boundary` that distinguishes content blocks in the message. Each block has its own `Content-Type` and `Content-Transfer-Encoding` that you can use to decode its data.

```txt
...
MIME-Version: 1.0
Content-Type: multipart/alternative;
  boundary="----=_Part_6675479_1563466077.1711038453276"

------=_Part_6675479_1563466077.1711038453276
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

------=_Part_6675479_1563466077.1711038453276
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

------=_Part_6675479_1563466077.1711038453276
```

You can use MIME data to get the complete information about a specific message, including the multiple formats it might accommodate. For example, the sample above offers both a plaintext and HTML version of the body content.

## Get MIME data from messages

When you set the `fields` query parameter to `raw_mime` on a [Get Message request](/docs/reference/api/messages/get-messages-id/), Nylas returns the `grant_id`, `object`, `id`, and `raw_mime` fields only.

```bash
curl --request GET \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/<MESSAGE_ID>/?fields=raw_mime' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json'
```

```json {7} [group_2-Response (JSON)]
{
  "request_id": "1",
  "data": {
    "grant_id": "<NYLAS_GRANT_ID>",
    "object": "message",
    "id": "<MESSAGE_ID>",
    "raw_mime": "<BASE64URL_ENCODED_STRING>"
  }
}
```

The `raw_mime` field contains all of the Base64url-encoded MIME data from the message, starting from the `MIME-Version` header. You can use the `boundary` value to separate blocks of content within the message.

## Send messages with MIME data

You can include MIME data in a [Send Message request](/docs/reference/api/messages/send-message/) by: - Setting the `mime` form field in a `multipart/form-data` request. - Including the query parameter `type=mime`

```bash {6}
curl --location 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send?type=mime' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--form 'mime="MIME-Version: 1.0
Subject: Test Raw MIME
From:  sender <sender@mail.example.com>
To: receiver <receiver@mail.example.com>
Content-Type: multipart/alternative; boundary=\"000000000000fda5260624af9e86\"

--000000000000fda5260624af9e86
Content-Type: text/plain; charset=\"UTF-8\"

Helloworld

--000000000000fda5260624af9e86
Content-Type: text/html; charset=\"UTF-8\"

<div dir=\"ltr\">Helloworld</div>

--000000000000fda5260624af9e86--"'
```

## Related resources

- [Debug invisible characters in email](https://cli.nylas.com/guides/debugging-invisible-characters-email) — find and fix zero-width characters, BOM bytes, and encoding issues in message headers and body content