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
Section titled “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.
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": "[email protected]" }], "cc": [{ "name": "Billing", "email": "[email protected]" }] }'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.", },});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.", },)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 for the full field list, including reply_to, send_at, and tracking options.
Send an Outlook email with an attachment
Section titled “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.
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": "[email protected]" }], "attachments": [{ "filename": "invoice-q3.pdf", "content_type": "application/pdf", "content": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9..." }] }'import fs from "node:fs";
const sent = await nylas.messages.send({ identifier: grantId, requestBody: { subject: "Your Q3 invoice", body: "Hi Kim, the signed invoice is attached.", attachments: [{ filename: "invoice-q3.pdf", contentType: "application/pdf", content: fs.readFileSync("invoice-q3.pdf").toString("base64"), }], },});import base64
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.", "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
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “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 is Outlook-only, which is the main reason teams reach for a unified layer when they add a second provider.
What’s next
Section titled “What’s next”- How to list Microsoft email messages to read Outlook mail with the same grant
- How to send emails with attachments for the multipart path and files up to 25MB
- Sending messages with Nylas for drafts, scheduled sends, and the full request field list
- Email API overview for threads, folders, and message tracking