Only show these results:

Send email messages with the Nylas Email API

📝 This page discusses both Nylas v2.x and v3. For more information about the newest version, see the Nylas v3 documentation.

Nylas offers multiple ways to send email messages. This page describes how to choose the best method for your Nylas application, how to create and send a draft email message, and how to send an email message without creating a draft.

Choose how to send email messages

Nylas offers two different ways to send email messages:

  • Create and send a draft: This method is ideal for preparing email messages that don't need to be sent immediately. Drafts are synced to the provider's Draft folder, if possible.
  • Send email message without creating draft: This method is ideal for sending a small number of email messages without saving them as drafts first. Email messages are synced to the provider's Sent folder, if possible.

In both cases, the sending operation is synchronous (meaning Nylas sends items one at a time) and the request blocks until the submission either succeeds or fails. If the submission fails, the Nylas Send API does not automatically try to send the email message again. For more information, see Deliverability for drafts and Send endpoint.

Create and send a draft

If you want to prepare an email message that doesn't need to be sent immediately, you can create a draft and send it later. When you create a draft with Nylas, it's synced with the provider. You can access it and make updates as long as it isn't deleted.

Create and send a draft in v3

To create a draft in Nylas v3, make a Create Draft request and include any relevant information, or use the Nylas SDKs.

🔍 All parameters for a Create Draft request are optional. If you make the request with no parameters, Nylas creates a draft with no content.

curl --request POST \
--url https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/drafts \
--header 'Authorization: Bearer <NYLAS_API_KEY_OR_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"subject": "From Nylas",
"to": [
{
"email": "[email protected]",
"name": "Dorothy Vaughan"
}
],
"cc": [
{
"email": "George Washington Carver",
"name": "[email protected]"
}
],
"bcc": [
{
"email": "Albert Einstein",
"name": "[email protected]"
}
],
"reply_to": [
{
"email": "[email protected]",
"name": "Stephanie Kwolek"
}
],
"body": "This email was sent using the Nylas email API. Visit https://nylas.com for details.",
"tracking_options": {
"opens": true,
"links": true,
"thread_replies": true,
"label": "hey just testing"
}
}'
import 'dotenv/config'
import Nylas from 'nylas'

const NylasConfig = {
apiKey: process.env.NYLAS_API_KEY,
apiUri: process.env.NYLAS_API_URI,
}

const nylas = new Nylas(NylasConfig)
const identifier = process.env.NYLAS_GRANT_ID

const createDraft = async () => {
try {
const draft = {
subject: "Your Subject Here",
to: [{ name: "Recipient Name", email: "[email protected]" }],
body: "Your email body here.",
}

const createdDraft = await nylas.drafts.create({
identifier,
requestBody: draft
})

console.log('Draft created:', createdDraft)

} catch (error) {
console.error('Error creating draft:', error)
}
}

createDraft()
from dotenv import load_dotenv
load_dotenv()

import os
import sys
from nylas import Client

nylas = Client(
os.environ.get('NYLAS_API_KEY'),
os.environ.get('NYLAS_API_URI')
)

grant_id = os.environ.get("NYLAS_GRANT_ID")
email = os.environ.get("EMAIL")

draft = nylas.drafts.create(
grant_id,
request_body={
"to": [{ "name": "Name", "email": email }],
"reply_to": [{ "name": "Name", "email": email }],
"subject": "Your Subject Here",
"body": "Your email body here.",
}
)

print(draft)
require 'nylas'

nylas = Nylas::Client.new(api_key: 'API_KEY')
file = Nylas::FileUtils.attach_file_request_builder("RubyLogo.png")

request_body = {
subject: "From Nylas",
body: 'This email was sent using the ' +
'Nylas Email API. ' +
'Visit https://nylas.com for details.',
to: [{ name: "Nylas",
email: "[email protected]"}],
cc: [{ email: '[email protected]',
name: 'Dorothy Vaughan' }],
bcc: [{ email: '[email protected]',
name: 'Hedy Lamarr' }],
attachments: [file]
}

draft, _ = nylas.drafts.create(identifier: "<GRANT_ID>", request_body: request_body)

puts "Draft \"#{draft[:subject]}\" was created with ID: #{draft[:id]}"
import com.nylas.NylasClient;
import com.nylas.models.*;
import com.nylas.util.FileUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CreateDraft {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
CreateAttachmentRequest attachment = FileUtils.attachFileRequestBuilder("src/main/java/JavaLogo.png");

List<CreateAttachmentRequest> request = new ArrayList<>();
request.add(attachment);

CreateDraftRequest requestBody = new CreateDraftRequest.Builder().
to(Collections.singletonList(new EmailName("[email protected]", "Nylas"))).
cc(Collections.singletonList(new EmailName("[email protected]", "Dorothy Vaughan"))).
bcc(Collections.singletonList(new EmailName("[email protected]", "Hedy Lamarr"))).
subject("With Love, from Nylas").
body("This email was sent using the Nylas Email API. Visit https://nylas.com for details.").
attachments(request).
build();

Response<Draft> drafts = nylas.drafts().create("<GRANT_ID>"), requestBody);

System.out.println("Draft " + drafts.getData().getSubject() + " was created with ID " + drafts.getData().getId());
}
}
import com.nylas.NylasClient
import com.nylas.models.*
import com.nylas.util.FileUtils

fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = "<NYLAS_API_KEY>")
val attachment: CreateAttachmentRequest = FileUtils.attachFileRequestBuilder("src/main/kotlin/Kotlin_Logo.png")

val requestBody = CreateDraftRequest(
to = listOf(EmailName("[email protected]", "Nylas")),
cc = listOf(EmailName("[email protected]", "Dorothy Vaughan")),
bcc = listOf(EmailName("[email protected]", "Hedy Lamarr")),
subject = "With Love, from Nylas",
body = "This email was sent using the Nylas Email API. Visit https://nylas.com for details.",
attachments = listOf(attachment)
)

val draft = nylas.drafts().create("<GRANT_ID>", requestBody).data

print("Draft " + draft.subject + " was created with ID: " + draft.id)
}

When you're ready, you can send the draft by making a Send Draft request or by using the SDKs, as in the examples below.

from dotenv import load_dotenv
load_dotenv()

import os
import sys
from nylas import Client

nylas = Client(
os.environ.get('NYLAS_API_KEY'),
os.environ.get('NYLAS_API_URI')
)

grant_id = os.environ.get("NYLAS_GRANT_ID")
draft_id = os.environ.get("DRAFT_ID")

draft = nylas.drafts.send(
grant_id,
draft_id
)

print(draft)
require 'nylas'

nylas = Nylas::Client.new(api_key: 'API_KEY')
draft, _ = nylas.drafts.send(identifier: "<GRANT_ID>", draft_id: "{DRAFT_ID}")

puts "Draft \"#{draft[:subject]}\" was sent with ID #{draft[:id]}"
import com.nylas.NylasClient;
import com.nylas.models.*;

public class SendDraft {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
Response<Message> draft = nylas.drafts().send("<GRANT_ID>", "<DRAFT_ID>");

System.out.println(draft.getData());
}
}
import com.nylas.NylasClient

fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = "<NYLAS_API_KEY>")
val draft = nylas.drafts().send("<GRANT_ID>", "<DRAFT_ID>")

print(draft.data)
}

Create and send a draft in v2

To create a draft in Nylas v2, make a POST /drafts request.

curl --location --request POST 'https://api.nylas.com/drafts/' \
--header 'Authorization: Bearer <access_token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"subject": "From Nylas",
"to": [{
"email": "[email protected]",
"name": "Nylas"
}],
"from": [{
"email": "[email protected]",
"name": "Your Name"
}],
"reply_to": [{
"name": "Nylas",
"email": "[email protected]"
}],
"reply_to_message_id": "1d00e908341a4a889ba4",
"body": "This email was sent using the Nylas email API. Visit https://nylas.com for details.",
"file_ids": [ "0a512d9b79584e989ca7" ]
}'

🔍 All parameters for a Create Draft request are optional. If you make the request with no parameters, Nylas creates a draft with no content.

The following parameters are useful to keep in mind as you create your request:

  • reply_to: Includes names and email addresses that Nylas uses to set a Reply-to address in the message's Reply-to header.
    • A Reply-to address is where replies to the email message are sent. This doesn't have to be the same as the From address.
    • Not all providers support setting a Reply-to address in drafts.
  • reply_to_message_id: The ID of the email message that you're replying to.
  • file_ids: Includes IDs of files that you attached to the draft.

You can also create a draft using the Nylas SDKs, as in the following examples.

require 'nylas'

nylas = Nylas::API.new(APP_ID, APP_SECRET, ACCESS_TOKEN)
file = nylas.files.create(file: File.open(File.expand_path('RubyLogo.png'), 'r')).to_h
draft = nylas.drafts.create(to: [{ email: '[email protected]', name: 'Nylas' }],
cc: [{ email: '[email protected]',
name: 'Dorothy Vaughan' }],
bcc: [{ email: '[email protected]',
name: 'Hedy Lamarr' }],
subject: 'From Nylas',
body: 'This email was sent using the ' +
'Nylas Email API. ' +
'Visit https://nylas.com for details.',
file_ids: [file[:id]])

puts "Draft Id: #{draft.id} | Draft Version: #{draft.version}"
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import com.nylas.*;

public class CreateDraft {
public static void main(String[] args) throws RequestFailedException, IOException {
NylasClient client = new NylasClient();
NylasAccount account = client.account("<ACCESS_TOKEN>");
Files files = account.files();

byte[] myFile = java.nio.file.Files.readAllBytes(
Paths.get("src/main/java/JavaLogo.png"));
File upload = files.upload("JavaLogo.png", "image/png", myFile);

Draft draft = new Draft();
draft.setTo(List.of(new NameEmail("Nylas", "[email protected]")));
draft.setCc(List.of(new NameEmail("Dorothy Vaughan","[email protected]")));
draft.setBcc(List.of(new NameEmail("Hedy Lamarr","[email protected]")));
draft.setSubject("With Love, from Nylas");
draft.setBody("This email was sent using the Nylas Java email API. Visit https://nylas.com for details.");
draft.attach(upload);

draft = account.drafts().create(draft);

System.out.println("Draft " + draft.getSubject() + " was created with ID " + draft.getId());
}
}

When you're ready, you can send the draft by making a POST /send request or using the Nylas SDKs. You must specify the draft_id for both methods, and the version for the API call.

⚠️ Your request will fail if Nylas finds a version of the draft on the provider that is newer than the one you're trying to send. To get the latest version, make a GET /draft/{draft_id} request.

curl -X POST 'https://api.nylas.com/send' \
-H 'Authorization: Bearer <access_token>' \
-d '{
"draft_id": "{draft_id}",
"version": 0
}'
require 'nylas'

nylas = Nylas::API.new(APP_ID, APP_SECRET, ACCESS_TOKEN)
draft = nylas.drafts.find("{draft_id}")

draft.send!
import java.io.IOException;
import com.nylas.*;

public class SendDraft {
public static void main(String[] args) throws RequestFailedException, IOException {
NylasClient client = new NylasClient();
NylasAccount account = client.account("<ACCESS_TOKEN>");
Draft draft = account.drafts().get("<DRAFT_ID>");

account.drafts().send(draft);
}
}

Create and send an email message

If you want to create and send an email message immediately, you can do so without creating a draft.

Create and send an email message in v3

To create and send an email message in Nylas v3, make a Send Message request. You can also create and send an email message using the Nylas SDKs, as in the examples below.

app.get("/nylas/send-email", async (req, res) => {
try {
const sentMessage = await nylas.messages.send({
identifier: process.env.USER_GRANT_ID,
requestBody: {
to: [{ name: "Name", email: process.env.EMAIL }],
replyTo: [{ name: "Name", email: process.env.EMAIL }],
subject: "Your Subject Here",
body: "Your email body here.",
},
});

res.json(sentMessage);
} catch (error) {
console.error("Error sending email:", error);
}
});
from dotenv import load_dotenv
load_dotenv()

import os
import sys
from nylas import Client

nylas = Client(
os.environ.get('NYLAS_API_KEY'),
os.environ.get('NYLAS_API_URI')
)

grant_id = os.environ.get("NYLAS_GRANT_ID")
email = os.environ.get("EMAIL")

message = nylas.messages.send(
grant_id,
request_body={
"to": [{ "name": "Name", "email": email }],
"reply_to": [{ "name": "Name", "email": email }],
"subject": "Your Subject Here",
"body": "Your email body here.",
}
)

print(message)
require 'nylas'

nylas = Nylas::Client.new(api_key: 'API_KEY')
file = Nylas::FileUtils.attach_file_request_builder("Ruby_Logo.png")

request_body = {
subject: "With Love, from Nylas",
body: "This email was sent using the <b>Ruby SDK</b> for the Nylas Email API. Visit <a href='https://nylas.com'>Nylas.com</a> for details.",
to: [{name: "Nylas", email: "[email protected]"}],
attachments: [file]
}

email = nylas.messages.send(identifier: "<GRANT_ID>", request_body: request_body)

puts email
import com.nylas.NylasClient;
import com.nylas.models.*;
import com.nylas.util.FileUtils;
import java.util.ArrayList;
import java.util.List;

public class SendEmails {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();

List<EmailName> emailNames = new ArrayList<>();
emailNames.add(new EmailName("[email protected]", "Nylas"));

CreateAttachmentRequest attachment = FileUtils.attachFileRequestBuilder("src/main/java/JavaLogo.png");
List<CreateAttachmentRequest> request = new ArrayList<>();
request.add(attachment);

SendMessageRequest requestBody = new SendMessageRequest.Builder(emailNames).
subject("With Love, from Nylas").
body("This email was sent using the <b>Java SDK</b> for the Nylas Email API." +
" Visit <a href='https://nylas.com'>Nylas.com</a> " +
"for details.").
attachments(request).
build();

Response<Message> email = nylas.messages().send("<GRANT_ID>", requestBody);

System.out.println(email.getData());
}
}
import com.nylas.NylasClient
import com.nylas.models.*
import com.nylas.util.FileUtils

fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = dotenv["NYLAS_API_KEY"])
val attachment: CreateAttachmentRequest = FileUtils.attachFileRequestBuilder("src/main/kotlin/Kotlin_Logo.png")
val emailNames : List<EmailName> = listOf(EmailName("[email protected]", "Nylas"))

val requestBody : SendMessageRequest = SendMessageRequest.
Builder(emailNames).
subject("With Love, from Nylas").
body("This email was sent using the Nylas email API. Visit https://nylas.com for details.").
attachments(listOf(attachment)).
build()

val email = nylas.messages().send(dotenv["GRANT_ID"], requestBody)

print(email.data)
}

Create and send an email message in v2

To create and send an email message in Nylas v2, make a POST /send request or use the Nylas SDKs.

curl --location --request POST 'https://api.nylas.com/send' \
--header 'Authorization: Bearer <access_token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"subject": "From Nylas",
"to": [{
"email": "[email protected]",
"name": "Nylas"
}],
"from": [{
"email": "[email protected]",
"name": "Your Name"
}],
"reply_to": [{
"name": "Nylas",
"email": "[email protected]"
}],
"reply_to_message_id": "1d00e908341a4a889ba4",
"body": "This email was sent using the Nylas email API. Visit https://nylas.com for details.",
"file_ids": [ "0a512d9b79584e989ca7" ]
}'
require 'nylas'

nylas = Nylas::API.new(APP_ID, APP_SECRET, ACESS_TOKEN)
file = nylas.files.create(file: File.open(File.expand_path('RubyLogo.png'), 'r')).to_h

nylas.send!(
to: [{ email: '[email protected]', name: 'Nylas' }],
cc: [{ email: '[email protected]',
name: 'Dorothy Vaughan' }],
bcc: [{ email: '[email protected]',
name: 'Hedy Lamarr' }],
subject: 'From Nylas',
body: 'This email was sent using the ' +
'Nylas email API. ' +
'Visit https://nylas.com for details.',
file_ids: [file[:id]]
).to_h
import java.lang.Exception;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.List;
import com.nylas.*;

public class SendEmail {
public static void main(String[] args) throws RequestFailedException, IOException {
NylasClient client = new NylasClient();
NylasAccount account = client.account("<ACCESS_TOKEN>");
Files files = account.files();

byte[] myFile = java.nio.file.Files.readAllBytes(
Paths.get("src/main/java/JavaLogo.png"));
File upload = files.upload("JavaLogo.png", "image/png", myFile);

Draft draft = new Draft();

draft.setSubject("With Love, from Nylas");
draft.setBody("This email was sent using the <b>Java SDK</b> for the Nylas Email API. Visit <a href='https://nylas.com'>Nylas.com</a> for details.");
draft.setTo(List.of(new NameEmail("Nylas", "[email protected]")));
draft.attach(upload);

account.drafts().send(draft);
}
}

Draft deliverability and the Send endpoint

Send operations are synchronous (meaning Nylas sends items one at a time), and the request blocks until the submission succeeds or fails. If the request fails, the Nylas Send API does not automatically try to send the email message again.

💡 A successful request to the Send endpoint can sometimes take up to two minutes for self-hosted Exchange accounts, though the average send time is approximately two seconds. To ensure that you receive a response from Nylas, set the maximum timeout to 150 seconds.

Nylas recommends that you apply a backoff strategy when the Send API returns HTTP 503 errors. Your application might need to wait between 10–20 minutes, or else SMTP servers might continue to refuse connections for the affected end user.

For information on the number of email messages you can send per day, see the Provider rate limits documentation. If large-volume sending continues to fail for your application, Nylas recommends you switch to a transactional sending service (for example, Mailgun, Sendgrid, Mandrill, or Amazon SES).

Sending errors

Sometimes, delivery of email messages might fail if the end user's email gateway rejects the message. This can happen for a number of reasons, including illegal attachment data, bad credentials, or rate-limiting.

If the email message is submitted successfully, the server responds with a 200 OK HTTP response. If the message is not submitted, the server responds with an error code.

Status Code Type Description
200 OK Your email message has been successfully submitted for sending.
400 Bad request Your request was not formed properly, or contains an invalid parameter. The most common cause is invalid JSON.
402 Message rejected The provider rejected the email message because of its content or recipients. If the error includes "Sending to at least one recipient failed", it means that your email message might have been delivered to only a subset of recipients.
403 Unauthorized The server was not able to authenticate with the provider. Re-authenticate the end user and try again.
422 Mail provider error An error occurred while the provider was sending the email message. See the server_error parameter in the response JSON for more information.
429 Quota exceeded The end user has exceeded their provider's sending quota. There is no reliable way to determine these limits. Wait and try again later.
429 Account throttled The account is in a throttled state and the mail server has asked Nylas to temporarily stop making requests. Wait and try again later.
429 Nylas API rate limit You made too many requests to the Nylas API too quickly. Wait and try again later. For more information, see the Rate limiting documentation.
503 Service unavailable Nylas encountered an error while connected to the provider. Wait and try again.

⚠️ If any participant email addresses contain non-ASCII characters (for example, characters with accents or other diacritics), email message delivery fails and Nylas returns a 402 error with the "Sending to at least one recipient failed" message. Currently, Nylas cannot send email messages to email addresses that contain these special characters.

The response body also contains a JSON object with information about the specific error, including the attributes in the following table.

Parameter Type Description
type string The type of error encountered.
message string A brief, human-readable description of the error.
server_error string (Optional) The original error returned by the end user's email server.

Bounce detection in v3

📝 Note: Bounce detection is available for Gmail and Microsoft Graph only.

In v3, Nylas monitors for and notifies you when an end user gets an email message bounce notification. Bounce notifications are sent by an email recipient's provider when the message can't be delivered, and usually include a detailed error message. When an end user receives a notification that a message bounced, Nylas scans it and grabs the cause from the error message.

Email messages can bounce for a variety of reasons, and can be considered either "soft" bounces (those with a temporary root cause, like the recipient's inbox being full) or "hard" bounces (those with a permanent root cause, like the recipient's email address no longer exists). Currently, v3 supports hard bounces only, and Nylas publishes mailbox_unavailable and domain_not_found bounces. For more information about bounce detection, see Nylas' message.bounce_detected webhook schema and Soft vs. Hard Bounce - what's the difference? on the Nylas blog.

The email message ID header

Sending an email using the Nylas Email API creates a unique message_id_header in the sender's database, similar to the example below.

[email protected]   

This value is required for the provider's SMTP server, and is part of the standard protocol when using Nylas as an email client. The header is visible only on the sender's database, and is not an email object that you can use or update.

The provider's SMTP server might modify this value during the sending process. Nylas recommends you avoid using this message_id_header with the @mailer.nylas.com domain for email configuration.

What's next?

Video walkthroughs

Prefer video? You can watch Nylas' livestream, Coding with Nylas.

Send and read email messages using PHP

Send email messages using Rust and C#

Send and read email messages using Node-Red