# How to send Outlook email

Source: https://developer.nylas.com/docs/cookbook/email/send-outlook-email/

Sending mail through Outlook with the Microsoft Graph API means registering an Azure AD app, requesting the `Mail.Send` permission, chasing admin consent on enterprise tenants, then base64-encoding every attachment into a JSON `Message` resource before you POST to `/me/sendMail`. If you also support Gmail, you build a second integration from scratch.

This recipe shows the shorter path: send from a connected Microsoft 365 or Outlook mailbox with one Nylas call. No Azure app registration on your side, no SMTP server, and the same request shape you'd use for Google or IMAP accounts.

## Send an Outlook email

Send Outlook mail with a single `POST /v3/grants/{grant_id}/messages/send` request, the same endpoint that serves all 6 providers Nylas supports. The `grant_id` identifies the connected Microsoft 365 mailbox, and the API relays the message through Microsoft Graph under the user's own account. The body requires only `to`, plus optional `subject`, `body`, `cc`, `bcc`, and `reply_to` arrays.

The request below sends an HTML email from the grant's mailbox. Each recipient is an object with `email` and an optional `name`, spread across the `to`, `cc`, and `bcc` arrays. The send is synchronous: the request blocks until Microsoft accepts or rejects the message, so a `200` response means it's on its way to all recipients, not queued for later.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "subject": "Your Q3 invoice",
    "body": "Hi Kim, your invoice for Q3 is ready. Reply here with any questions.",
    "to": [{ "name": "Kim Townsend", "email": "kim@example.com" }],
    "cc": [{ "name": "Billing", "email": "billing@example.com" }]
  }'
```

```js [sendOutlook-Node.js SDK]
const sent = await nylas.messages.send({
  identifier: grantId,
  requestBody: {
    subject: "Your Q3 invoice",
    body: "Hi Kim, your invoice for Q3 is ready. Reply here with any questions.",
    to: [{ name: "Kim Townsend", email: "kim@example.com" }],
    cc: [{ name: "Billing", email: "billing@example.com" }],
  },
});
```

```python [sendOutlook-Python SDK]
sent = nylas.messages.send(
    grant_id,
    request_body={
        "subject": "Your Q3 invoice",
        "body": "Hi Kim, your invoice for Q3 is ready. Reply here with any questions.",
        "to": [{"name": "Kim Townsend", "email": "kim@example.com"}],
        "cc": [{"name": "Billing", "email": "billing@example.com"}],
    },
)
```

The `from` field is optional. When you omit it, the API uses the grant's own address and display name, so the recipient sees the message coming straight from the connected Outlook account. See [Sending messages with Nylas](/docs/v3/email/send-email/) for the full field list, including `reply_to`, `send_at`, and tracking options.

## Send an Outlook email with an attachment

Add files by including an `attachments` array on the same send request. Each item carries the Base64-encoded `content`, a `filename`, and a `content_type` MIME string. For total request bodies under 3MB this JSON path is the simplest option, since everything travels in one call without a separate upload step.

The example below attaches a PDF invoice to the Outlook message. Base64 encoding inflates file size by about 33%, and the 3MB ceiling covers the entire HTTP request, not only the file. For anything larger, switch to the `multipart/form-data` path documented in [How to send emails with attachments](/docs/cookbook/email/attachments/send-attachments/).

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "subject": "Your Q3 invoice",
    "body": "Hi Kim, the signed invoice is attached.",
    "to": [{ "name": "Kim Townsend", "email": "kim@example.com" }],
    "attachments": [{
      "filename": "invoice-q3.pdf",
      "content_type": "application/pdf",
      "content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9..."
    }]
  }'
```

```js [sendOutlookAttach-Node.js SDK]


const sent = await nylas.messages.send({
  identifier: grantId,
  requestBody: {
    subject: "Your Q3 invoice",
    body: "Hi Kim, the signed invoice is attached.",
    to: [{ name: "Kim Townsend", email: "kim@example.com" }],
    attachments: [{
      filename: "invoice-q3.pdf",
      contentType: "application/pdf",
      content: fs.readFileSync("invoice-q3.pdf").toString("base64"),
    }],
  },
});
```

```python [sendOutlookAttach-Python SDK]


with open("invoice-q3.pdf", "rb") as f:
    encoded = base64.b64encode(f.read()).decode()

sent = nylas.messages.send(
    grant_id,
    request_body={
        "subject": "Your Q3 invoice",
        "body": "Hi Kim, the signed invoice is attached.",
        "to": [{"name": "Kim Townsend", "email": "kim@example.com"}],
        "attachments": [{
            "filename": "invoice-q3.pdf",
            "content_type": "application/pdf",
            "content": encoded,
        }],
    },
)
```

To embed an image in the HTML body instead of attaching it, set a `content_id` on the attachment and reference it with a matching `cid:` in an `<img>` tag. Note that `content_disposition` isn't supported for Microsoft accounts, so don't rely on it when targeting Outlook.

## Nylas vs the Microsoft Graph sendMail API

The Microsoft Graph equivalent is `POST /me/sendMail`, which sends a `Message` resource through the signed-in user's mailbox. It works well if Outlook is the only provider you support and you've already built the Azure AD plumbing. The table below compares the two for a typical multi-provider send, with the unified path in bold.

| Concern | Microsoft Graph `POST /me/sendMail` | **Nylas `POST /v3/grants/{grant_id}/messages/send`** |
| --- | --- | --- |
| Setup | Azure AD app, `Mail.Send` permission, admin consent | **One grant, one API key** |
| Attachments | Base64 inside the `Message`; 3MB inline, large files need an upload session | **Base64 under 3MB, `multipart/form-data` up to 25MB** |
| Multi-provider | Outlook only; rebuild for Gmail | **Same request for Outlook, Gmail, Yahoo, iCloud, IMAP, EWS** |
| Sent folder | Saved to Sent Items automatically | **Saved to the provider's Sent folder automatically** |

Both routes send from the user's real mailbox, so deliverability and the `From` address match what the account owner would send manually. The difference is integration surface: one connector covers every provider instead of a per-vendor SDK.

## Things to know about sending Outlook email

Outlook sends through Nylas relay to Microsoft Graph, so the same throttling, mailbox rules, and folder behavior that apply to a native Graph integration apply here too. These details affect retries, the visible sender, and sending on behalf of another account.

### Messages send from the user's own address

By default the message goes out as the grant's mailbox, with that account's name and address in the `From` header. Recipients see a normal Outlook email from the connected user, not from a third-party platform. Omitting the `from` field is the common case for transactional mail like a single invoice or a password reset.

### Microsoft throttling and 429 responses

Microsoft Graph throttles outbound mail per mailbox, currently around 30 messages per minute and 10,000 recipients per day for Exchange Online. When you exceed a limit, Graph returns `429 Too Many Requests` with a `Retry-After` header. Don't retry immediately. Wait the number of seconds in `Retry-After`, then resend.

### Sent mail lands in Sent Items

A successful send writes a copy to the mailbox's Sent Items folder, the same as if the user clicked Send in Outlook. Microsoft stores that folder under the internal name `sentitems`, which is worth knowing if you later list or filter sent messages by folder ID rather than display name.

### Shared mailboxes and send-as

To send as a shared mailbox or another address, the grant needs Microsoft Send As or Send on Behalf permission for that mailbox, granted by a tenant admin. Set the delegated address in the `from` field. Without the permission, Graph rejects the send, so confirm the delegation in Exchange before relying on it in production.

### One connector covers Outlook and Gmail

A single Nylas connector and the same `/messages/send` endpoint serve Outlook and Gmail accounts, so you write the send path once. The official `POST /me/sendMail` reference in the [Microsoft Graph sendMail docs](https://learn.microsoft.com/en-us/graph/api/user-sendmail) is Outlook-only, which is the main reason teams reach for a unified layer when they add a second provider.

## What's next

- [How to list Microsoft email messages](/docs/cookbook/email/messages/list-messages-microsoft/) to read Outlook mail with the same grant
- [How to send emails with attachments](/docs/cookbook/email/attachments/send-attachments/) for the multipart path and files up to 25MB
- [Sending messages with Nylas](/docs/v3/email/send-email/) for drafts, scheduled sends, and the full request field list
- [Email API overview](/docs/v3/email/) for threads, folders, and message tracking