Got questions? Contact support.

Overview

The Nylas Sync Engine provides a modern API that works with existing email providers. It makes it easy to integrate with your users’ email data, and eliminates the complexity of old protocols like IMAP and MIME.

The API is designed around the REST ideology, providing simple and predictable URIs to access and modify objects. Requests support standard HTTP methods like GET, PUT, POST, and DELETE. Response bodies are always UTF-8 encoded JSON objects, unless explicitly documented otherwise.

Threads are a first-class object, allowing you to build beautiful mail applications that behave the way users have come to expect. Actions like archiving or deleting are performed on threads, not individual messages.

Tags are used to group threads, and a thread can have zero or more tags. Note: tags are not equivalent to IMAP folders or Gmail labels, although these properties may be accessed via tags.

Nylas uses OAuth2 for authentication with a specific user’s account. Subsequent API requests are made with an access_token for that user, secured by HTTP basic auth over SSL (TLS). The user auth flow is documented below.

Help

If you need help, you can contact support or chat live with our engineering team in #nylas on freenode.

Namespaces

Namespaces are essentially references to linked accounts. They are the top-level unit of a user’s data. For example, a user who has one Exchange account and two Gmail accounts linked to Nylas will have three distinct namespaces.

The /n endpoint returns the list of namespaces you can access with the access token you provide. Generally, GET /n should be the first request you make after authenticating a new user. Typically, access tokens provide access to a single namespace, but this may change in the future.

Listing Namespaces

GET https://api.nylas.com/n

Response

[
    {
        "id": "awa6ltos76vz5hvphkp8k17nt",
        "object": "namespace",
        "namespace_id": "awa6ltos76vz5hvphkp8k17nt",
        "account_id": "c5zc216uat483slypx67mu8i3",
        "email_address": "ben.bitdiddle@gmail.com",
        "name": "Ben Bitdiddle",
        "provider": "Gmail"
    }
]

Getting a Single Namespace

The top-level URI will return information about a namespace with the given namespace_id.

GET https://api.nylas.com/n/<namespace_id>

Threads

Threads are the main object in Nylas. They can be read, archived, and deleted. All messages are part of a thread, even if that thread has only one message. Operations like flagging and marking as read are only done at the thread level.

Retrieving a Thread

GET https://api.nylas.com/n/<namespace_id>/threads/<thread_id>

The thread object includes useful information like subject, participants, and time of the most recently received message.

Sample response:

{
    "id": "evh5uy0shhpm5d0le89goor17",
    "object": "thread",
    "namespace_id": "awa6ltos76vz5hvphkp8k17nt",
    "subject": "Dinner Party on Friday",
    "last_message_timestamp": 1398229259,
    "first_message_timestamp": 1298229259,
    "participants": [
        {
            "name": "Ben Bitdiddle",
            "email": "ben.bitdiddle@gmail.com"
        },
        {
            "name": "Charles Mason",
            "email": "cmason@cmu.edu"
        },
        {
            "name": "Bill Rogers",
            "email": "wrogers@mit.edu"
        }
    ],
    "snippet": "Hey Bill, Looking forward to getting together for dinner on Friday. What can I bring? I have a couple bottles of wine or could put together",
    "tags": [
        {
            "name": "inbox",
            "id": "f0idlvozkrpj3ihxze7obpivh"
        },
        {
            "name": "unread",
            "id": "8keda28h8ijj2nogpj83yjep8"
        }
    ],
    "message_ids": [
        "251r594smznew6yhiocht2v29",
        "7upzl8ss738iz8xf48lm84q3e",
        "ah5wuphj3t83j260jqucm9a28"
    ],
    "draft_ids": [
        "251r594smznew6yhi12312saq"
    ],
    "version": 2
}

Retrieving all Messages in a Thread

See Message section.

Retrieving Many Threads

GET https://api.nylas.com/n/<namespace_id>/threads?<filter_parameters>

This API supports Filters, making it easy to return a subset of threads matching your needs. You can specify one or more filter parameters to return threads with a specific tag, from a specific sender, etc. For example, this request would return only threads in the user’s inbox:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=inbox

Filters also allow you to make more complex queries like the one below, which shows threads that include mark@nylas.com as a participant and are unread, ordered by date:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=unread&any_email=mark@nylas.com

Threads are returned in order of their latest message date, most recent first.

Pagination

The limit filter allows you to specify how many threads you would like returned. If your application only needs a few threads, you should explicitly provide a limit to improve performance. If your application needs to fetch a large number of threads, you can implement basic pagination using the offset filter. If a request returns less than limit threads, you have run out of threads.

If you are building an application that intends to sync all of the user’s threads, like a full-featured mail client, you should use the delta enpoint to avoid repeatedly paginating over the entire set of threads in the user’s inbox.

Participants

The list of thread participants includes everyone involved in the thread. The name field on each participant is the underlying phrase associated with their email address. In typical IMAP clients you set the phrase manually when you configure the account, so it’s possible for phrases to vary for the same email address, or for the phrase to be missing entirely. When Nylas displays lists of participants it does not consolidate copies of an email addresses with different phrases, because phrases are often overloaded to provide context. For example, this is a valid set of participants:

[
    {
        "name": "Bill Rogers",
        "email": "wrogers@mit.edu"
    },
    {
        "name": "Jon Smith (via Nylas Support)",
        "email": "support@nylas.com"
    },
    {
        "name": "Mark Tanner (via Nylas Support)",
        "email": "support@nylas.com"
    }
]

Nylas does not consolidate these two participants based on their email address support@nylas.com, because they could (and in this case do) represent two separate participants in the thread.

The name field may also be blank. In this case, you may want to display the email address or look up the email address in an external address book.

[
    {
        "name": "Bill Rogers",
        "email": "wrogers@mit.edu"
    },
    {
        "name": "",
        "email": "no-reply@example.com"
    }
]

Snippets

Nylas provides a snippet for each thread so that your application can preview message content without making additional API calls. The snippet is a small excerpt of text from the most recent message in the thread. It is automatically updated when messages are added to threads.

Snippets are always provided as plain text with HTML tags and other content stripped from the body. Their length varies based on the length of the underlying messages, and a thread may have an empty snippet if the message in thread has no body text.

Archiving, Starring, and Deleting

You can perform actions on threads, such as archiving and marking as read, using tags. For example, you can star a thread by adding the starred tag. See the tags documentation for more information.

Replying and Sending

See Drafts & Sending.

Tags

Tags are a powerful way to store metadata on threads and group them for the user. The unread tag, for example, indicates that a thread is unread. Other tags might be used to organize threads by project, categorize threads with attachments, or record whether an email had been handled by a task-management app.

Listing Tags

GET https://api.nylas.com/n/<namespace_id>/tags

Response

[
    {
        "id": "4zv7pgvihjvuptbwv57kiz62",
        "name": "inbox",
        "namespace_id": "awa6ltos76vz5hvphkp8k17nt",
        "object": "tag",
        "readonly": false
    },
    {
        "id": "76zrfd8ln5zo2swalu1yojhty",
        "name": "drafts",
        "namespace_id": "awa6ltos76vz5hvphkp8k17nt",
        "object": "tag",
        "readonly": false
    },
    ...
]

Getting a Single Tag

The response for a single tag includes the number of unread threads with that tag, as well as the total number of threads tagged.

GET https://api.nylas.com/n/<namespace_id>/tags/<tag_id>

Response

{
    "id": "4zv7pgvihjvuptbwv57kiz62",
    "name": "inbox",
    "namespace_id": "awa6ltos76vz5hvphkp8k17nt",
    "object": "tag",
    "readonly": false,
    "thread_count": 190,
    "unread_count": 7
}

Getting Threads with a Tag

You can list all of the threads with a given tag using a Tag Filter. The tag parameter can be a tag ID, such as 4zv7pgvihjvuptbwv57kiz62 or a tag name, like inbox or hiking.

GET https://api.nylas.com/n/<namespace_id>/threads?tag=<tag_id>

Canonical Tags

Nylas exposes a set of standard, canonical tags: an extended version of RFC-6154 mapped to the underlying folders / labels, etc. on each backend provider. A few of the standard tags, such as spam, may only be present if they are supported by the underlying email service.

  • inbox
  • archive
  • drafts
  • sent
  • spam
  • starred
  • unread
  • trash
  • unseen

Updating Tags & Performing Actions

You can add and remove tags from threads using a simple PUT request:

PUT https://api.nylas.com/n/<namespace_id>/threads/<thread_id>

Request body

{
    "add_tags": ["housing-search", "craigslist"],
    "remove_tags": ["unread"]
}

Adding and removing tags in the standard set allows you to perform actions on the user’s mailbox in a consistent, uniform way. Each of the changes below is synced back to the underlying mail provider (Exchange, Gmail, Yahoo, etc.)

  • Add archive to remove the thread from the user’s inbox. Removes the inbox tag.
  • Add trash to remove all other tags and queue the message for deletion.
  • Add unread to mark the thread as unread.
  • Add starred to star the thread. On non-Gmail backends, this ‘flags’ the message.
  • Remove unseen to mark that the thread has been displayed to the user.
  • Remove unread to mark the thread as read and also remove the unseen tag.
  • Remove starred to unstar the thread. On non-Gmail backends, this ‘unflags’ the message.

There are a few tags that you cannot add or remove:

  • drafts See Drafts for creating and updating drafts.
  • sent See Sending for sending mail.

Unread & Unseen

In addition to the standard “unread” state, Nylas exposes an additional state for each thread called “unseen.” The goal of shared “unseen” state is to prevent the same message from being displayed prominently across several applications if the user has chosen not to read it. Here’s a quick look at the difference between “unread” and “unseen” and the motivation behind “unseen”:

Unread (Threads & Messages):

  • Messages and threads should be marked as read when the user views them.
  • Messages may be collapsed or folded once they’ve been read.

Unseen (Threads Only):

  • Threads are given the unseen tag when new messages are appended.
  • Threads with the unseen tag may be highlighted in your app.
  • Threads should be marked as seen as soon as the thread’s snippet has been displayed, even if the user chooses not to interact with them.

You are not required to use the “unseen” state: removing the unread tag also removes the unseen tag as a fallback behavior. However, you should mark threads as seen whenever they are displayed within your app so that they are not presented as new content in other apps.

Creating Custom Tags

In addition to using the Nylas Sync Engine’s pre-defined tags like unread, archive, and sent, your application can define custom tags to store state and communicate with other mail apps. For example, your time saving mail client could tag messages withrevisit-later to retrieve them when the user was ready to read them. A flight-tracking app could add the tag flight-confirmation, making it easy for the user to pull up their boarding pass at the airport.

POST https://api.nylas.com/n/<namespace_id>/tags

Request body

{
    "name": "<new tag name>"
}

Changing custom tag names

PUT https://api.nylas.com/n/<namespace_id>/tags/<tag_id>

Request body

{
    "name": "<new_name>"
}

Response

{
    "id": "d121cvdyjhgacaqyymzjg5prl",
    "name": "housing-search",
    "object": "tag",
    "readonly": false
}

Note that only tags that were created via the API can be changed. You can’t
rename e.g. the sent or the unread tag.

Gmail Labels & IMAP Folders

Tags are similar to labels in Gmail, but Nylas presents a uniform interface across all providers including Exchange, Yahoo, and generic IMAP. It’s important to note that this consistent experience comes with an important limitation: though Nylas exposes tags for Gmail labels and IMAP folders, these tags cannot be added or removed from threads. Nylas does not allow changes to these tags and does not sync them back to underlying mail provider with the exception of its built-in canonical labels (unread, archive, trash, etc.)

What does that mean in practice? Here are some examples of things you can and cannot do with Gmail labels through Nylas:

Can I see if a message has been labeled ‘climbing’ in Gmail?

Yes. This Gmail label will be exposed as the tag climbing on the Nylas thread.

Can I add the ‘climbing’ label to a message in Gmail?

No. Although the Gmail label would appear as the climbing tag, this tag is read only. You can’t add or remove it from threads or rename it. This is important, because your application should work for users with stock IMAP and Exchange accounts as well as Gmail. Read-only tags contain the attribute "readonly": true in their representation.

Can I add the ‘starred’ label to a message in Gmail?

In general, tag changes aren’t synced back to Gmail but there are a few exceptions. Adding the Nylas starred tag will star the message in Gmail and perform the equivalent action on every other provider supported by Nylas. The need for a consistent behavior means that there are only a few tags this applies to: unread, archive, starred, inbox and trash.

Messages

Messages are a sub-object of threads. The content of a message is immutable (with the exception being drafts). Nylas does not support operations such as move or delete on individual messages; those operations should be performed on the message’s thread. All messages are part of a thread, even if that thread has only one message.

Retrieving a Message

GET https://api.nylas.com/n/<namespace_id>/messages/<message_id>

Sample Response

{
    "id": "84umizq7c4jtrew491brpa6iu",
    "object": "message",
    "subject": "Re: Dinner on Friday?",
    "from": [
        {
            "name": "Ben Bitdiddle",
            "email": "ben.bitdiddle@gmail.com"
        }
    ],
    "to": [
        {
            "name": "Bill Rogers",
            "email": "wbrogers@mit.edu"
        }
    ],
    "cc": [],
    "bcc": [],
    "date": 1370084645,
    "thread_id": "5vryyrki4fqt7am31uso27t3f",
    "files": [
        {
            "content_type": "image/jpeg",
            "filename": "walter.jpg",
            "id": "7jm8bplrg5tx0c7pon56tx30r",
            "size": 38633,
            "content_id": "ii_i2cg7byn1_1499bfd99727e569"
        }
    ],
    "snippet": "Sounds good--that bottle of Pinot should go well with the meal. I'll also bring a surprise for dessert. :) Do you have ice cream? Looking fo",
    "body": "<html><body>....</body></html>",
    "unread": true
}

Retrieving Many Messages

The messages endpoint supports Filters, making it easy to return a subset of messages matching your needs. You should specify one or more filter parameters to narrow your request. For example, you can return messages from a specific sender, with a particular subject, etc.

GET https://api.nylas.com/n/<namespace_id>/messages?<filter_parameters>

Sample Response

[
    <message_object>,
    <message_object>,
    <message_object>
]

Messages are returned order by date, most recent first.

Retrieving Messages in a Thread

One of the filter parameters available on messages is thread. Given a thread_id value, the API call will will return all messages in the thread.

GET https://api.nylas.com/n/<namespace_id>/messages?thread_id=<thread_id>

Marking a message as read

PUT https://api.nylas.com/n/<namespace_id>/messages/<message_id>
{
    "unread": false
}

Getting the raw contents of a message

If you need to access some specific email headers that are not exposed by our API (e.g: mailing-list specific headers) you can request the original message data by setting the Accept header to message/rfc822.

curl -H "Accept: message/rfc822" \
    https://api.nylas.com/n/<namespace_id>/messages/<message_id>
Delivered-To: ben.bitdiddle1861@gmail.com
Received: by 10.36.105.83 with SMTP id e80csp448398itc;
        Mon, 2 Mar 2015 22:32:19 -0800 (PST)
X-Received: by 10.140.146.6 with SMTP id 6mr57679712qhs.44.1425364337630;
        Mon, 02 Mar 2015 22:32:17 -0800 (PST)
Return-Path: <golang-nuts+bncBC35DTG33YGBB3NK2WTQKGQEPOXSM4Q@googlegroups.com>
Received: from mail-qg0-x23b.google.com (mail-qg0-x23b.google.com. [2607:f8b0:400d:c04::23b])
...

Drafts

A draft is a special kind of message which has not been sent, and therefore its body contents are mutable. Once sent, the body cannot be changed. Draft objects are identical to message objects sent via the API, except that they have an additional version parameter. A draft’s ID doesn’t change, but each time the draft is updated, its version parameter is updated as well. Having a constant ID is useful for caching and repeated querying, while the unique version is used to prevent conflicting operations.

Retrieving Drafts

GET  https://api.nylas.com/n/<namespace_id>/drafts
GET  https://api.nylas.com/n/<namespace_id>/drafts/<draft_id>

This endpoint supports filters, which allow you to fetch multiple drafts matching specific critera. The same parameters are supported as that of the messages endpoint.

Creating a Draft

POST https://api.nylas.com/n/<namespace_id>/drafts

Post body parameters:

  • subject
  • to
  • cc
  • bcc
  • thread_id
  • body
  • file_ids

Note that all of these parameters are optional. If omitted, an empty draft will still be created.

Sample Post Body

{
    "subject": "Dinner on Friday?",
    "to": [
        {
            "name": "Ben Bitdiddle",
            "email": "ben.bitdiddle@gmail.com"
        },
    ],
    "cc": [],
    "bcc": [],
    "body": "<html><body>....</body></html>",
    "file_ids": [
        "bgmzg0qp61oqrrmpadboiiyg3",
        "aikfl1kl73r69hevrm018jqzw"
    ]
    "version": 2
}

A successful response will contain the newly created Draft object.

Also note that creating a draft will fail if the files with the referenced file_ids have not been uploaded. See Files for more details on how to upload and reference attachments.

Replying to an existing thread

If the draft is a response to an existing thread, you should provide the thread’s ID in the thread_id parameter and omit the subject parameter. Note that you must explicitly specify the message’s recipients in the to, cc and bcc fields of the post body; this is to prevent any ambiguity about whom the message will be sent to.

{
    "thread_id": <thread_id>,
    "body": "<html><body>....</body></html>",
    "to": [
        {
            "name": "Bill Rogers",
            "email": "wbrogers@mit.edu"
        }
    ],
    "file_ids": [
        "bgmzg0qp61oqrrmpadboiiyg3",
        ...
    ],
}

Updating a draft

Updating a draft is as simple as issuing a PUT request to the draft’s URI.

PUT https://api.nylas.com/n/<namespace_id>/drafts/<draft_id>

Put body parameters:

  • version

The request body must contain the version of the draft you wish to update. Other fields are optional and will overwrite previous values.

Updating a draft returns a draft object with the same ID but different version. When submitting subsequent send or save actions, you must use this new version.

Deleting a draft

To delete a draft simply issue a DELETE request to the draft’s URI.

DELETE https://api.nylas.com/n/<namespace_id>/drafts/<draft_id>

Delete body parameters:

  • version

The request body must contain the version of the draft you wish to delete.
If the draft does not exist, this request will fail.

Sending a draft

The Nylas API provides a single API for sending both new messages and existing drafts. See Sending for more information.

Listing Threads with Drafts

In some scenarios, you may want to display all of the threads in the user’s inbox that have draft messages. To get a list of all threads with drafts, use the Threads API call with a filter on the drafts tag:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=drafts

Files

The files endpoint manages data attached to messages. If you’d like to add attachments to a draft, use this endpoint to upload the files first. The files endpoint is also used for listing and downloading existing files contained in a user’s mail data.

Retrieving a specific file’s metadata

GET https://api.nylas.com/n/<namespace_id>/files/<file_id>

Response:

{
    "id": "conefgqnnsvqlj64iu0lvsb7g",
    "object": "file",
    "namespace_id": "awa6ltos76vz5hvphkp8k17nt",
    "filename": "House-Blueprints.zip",
    "size": 3145728,
    "content_type": "application/zip",
    "message_ids": ["152ev3uktfrtk3y2subs4i9mn"],
}

Downloading a file

Files can be downloaded by appending /download to the URI. The body response will include the filename.

GET https://api.nylas.com/n/<namespace_id>/files/<file_id>/download

Uploading a new file

POST https://api.nylas.com/n/<namespace_id>/files

This endpoint is used to transfer files to Nylas, which must be done before adding them to a draft message. Data should be sent as multipart-form data with a single file field named file. An example of a correct request is shown below. Rather than using this endpoint directly, you may want to consider using one of the Nylas SDKs, which internally handle native data types and build the form request.

POST https://api.nylas.com/n/<namespace_id>/files HTTP/1.1
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------41184676334
Content-Length: 29278

-----------------------------41184676334
Content-Disposition: form-data; name="file"; filename="GrandCanyon.jpg"
Content-Type: image/jpeg

<<<Binary data here>>>

A successful upload will return an array with a single file object. This object’s ID may be added to subsequent draft updates to attach the file to a draft before sending.

Sample Response:

[
    {
        "content_type": "image/jpeg",
            "id": "3f7d6reg1k7hc2umqkz8gcfmo",
            "namespace_id": "agud8k5kr8tmnm8wg4y6appw4",
            "object": "file",
            "size": 29278
    }
]

Retrieving many files

This endpoint supports filters, which allow you to fetch multiple files matching specific critera. Inline attachments are not included in results.

As an example, the following will return all zip files. Note the / character in the content-type has been replaced by the percent-encoded value %2F.

GET https://api.inboxapp.com/n/<namespace_id>/files?content_type=application%2Fzip

Options

  • limit The maximum number of results to return. Defaults to 100 for performance. If limit is set too high, a request may fail with HTTP status code 400 to prevent excessively large response bodies.

  • offset Zero-based offset; use with limit for pagination of results.

  • message_id Return only files that are attached to a particular message.

  • filename Return only files that match the given filename

  • content_type (string) Return only files with this content-type. Note the / character in the content-type has been replaced by the percent-encoded value %2F.

A note on content-types

In the spirit of transcending MIME, Inbox only references content-types, and not mimetypes. The mimetype of a downloaded attachment is referred to as the content-type. All files are encoded either as UTF-8 or binary.

Sending

Nylas provides a single API for sending mail:

POST https://api.nylas.com/n/<namespace_id>/send

You can use this API in two ways:

Sending an Existing Draft

Perform a POST request with the POST body below to send an existing draft. If the message is sent successfully, the thread receives the sent tag. Sent drafts no longer appear in the user’s drafts list.

{
    "draft_id": "9nhhb7w3tinsn4zkg9vjr3cxz",
    "version": 2
}

Sending a New Message

You can send messages without saving them as drafts beforehand. Instead of providing a draft ID, simply provide the JSON of the message object you want to send.

If the message is in reply to an existing message, provide the reply_to_message_id key with the ID of the message you are replying to. Note that you must still explicitly specify the new message’s recipients in the to, cc and bcc fields of the post body; this is to prevent any ambiguity about whom the message will be sent to.

{
    "reply_to_message_id": "84umizq7c4jtrew491brpa6iu",
    "body" : "Sounds great! See you then.",

    "to": [
        {
            "name": "Bill",
            "email": "wbrogers@mit.edu"
        }
    ]
}

Handling Errors

In rare cases, message delivery can fail if the user’s email gateway rejects the message. This could happen for a number of reasons, including illegal attachment data, bad credentials, or rate limiting. If your message is sent successsfully, the server will respond with an HTTP response code of 200 OK. If your message couldn’t be sent, the server will respond with an appropriate error code.

Code Description
200 OK - Your message was sent.
400 Bad Request - Your request was malformed, or contained an invalid parameter.
402 Message Rejected - The mail provider rejected your message because of its content or recipients.
403 Unauthorized - The server was unable to authenticate with the user’s mail provider. Re-authenticate the user and try again.
429 Quota Exceeded - The user has exceeded their mail provider’s sending quota.
503 Service Unavailable - There was an error connecting to the user’s mail provider. Wait and try again.

In addition, the response body contains a JSON object with information about the specific error, including the following attributes:

  • message A brief human-readable description of the error.
  • server_error The original error returned by the user’s mail server.

Sample Response:

{
    "message": "Message too large",
    "server_error": "552 : 5.3.4 Message size exceeds fixed maximum message size",
    "type": "api_error"
}

Calendars

Nylas supports calendars and events with a variety of functionality. Each namespace has one or more calendars, and each calendar has a collection of individual events. Each event has a title and description as well as a list of participants.

The calendars endpoint is used to manage calendars which hold events. Calendars are quite simple, having only a name and description. Note: The read_only flag on a calendar indicates whether or not you can modify its properties or make changes to its events. Event changes are currently automatically synced back for Gmail and Exchange accounts.

Retrieving a list of calendars

GET https://api.nylas.com/n/<namespace_id>/calendars

Response:

[
    {
        "description": null,
        "id": "8n9cfm9ad2f7tul91czc5sh3p",
        "name": "default",
        "namespace_id": "14e5bn96uizyuhidhcw5rfrb0",
        "object": "calendar",
        "read_only": false
    },
    {
        "description": "google default calendar",
        "id": "ci0k1wfyv533ccgox4t7uri4h",
        "name": "example@gmail.com",
        "namespace_id": "14e5bn96uizyuhidhcw5rfrb0",
        "object": "calendar",
        "read_only": true
    }
]

From this response we can see that there are two available calendars. The first calendar is the user’s default calendar. When events are created, if a specific calendar is not provided, they will be added to this calendar. Additionally, there is a calendar being synced from a provider. In this situation we can see that the provider-backed calendar is marked as read_only and therefore events cannot be added to it through the Nylas API.

Options:

  • limit (Integer) Maximum number of results to return. Defaults to 100. If limit is set too high, a request may fail with HTTP status code 400 to prevent excessively large response bodies.
  • offset (Integer) Zero-based offset to be used with limit for pagination of results.

Like other endpoints, the metadata can be retrieved for a specific calendar by specifing its id as in the following:

GET https://api.nylas.com/n/<namespace_id>/calendars/<calendar_id>

Events

The events endpoint is used to manage events within a calendar.

Each event has a title and description as well as a list of participants and a when object that indicates the time and length of the event.

Retrieving a specific event’s metadata

GET https://api.nylas.com/n/<namespace_id>/events/<event_id>

Response:

{
    "object": "event",
    "id": "4ee4xbnx7pxdb9g7c2f8ncyto",
    "calendar_id": "ci0k1wfyv533ccgox4t7uri4h",
    "namespace_id": "14e5bn96uizyuhidhcw5rfrb0",
    "description": null,
    "location": null,
    "participants": [
        {
            "email": "example@gmail.com",
            "name": "Ben Bitdiddle",
            "status": "yes"
        }
    ],
    "read_only": false,
    "title": "Meeting with Ben Bitdiddle",
    "when": {
        "object": "timespan",
        "end_time": 1408123800,
        "start_time": 1408120200
    },
    "busy": true,
    "status": "confirmed", // other possible values: "tentative" and "cancelled"
}

Retrieving many events

This endpoint supports filters, which allow you to fetch multiple events matching specific critera.

Options:

  • limit (Integer) Maximum number of results to return. Defaults to 100. If limit is set too high, a request may fail with HTTP status code 400 to prevent excessively large response bodies.
  • offset (Integer) Zero-based offset to be used with limit for pagination of results.
  • event_id Return the event with the given id.
  • calendar_id Return events from the calendar with the given id.
  • title (String) Return events whose title matches the provided value.
  • description (String) Return events whose description matches the provided value.
  • location (String) Return events whose location matches the provided value.
  • starts_before (integer, Unix timestamp) Return events that start before this timestamp.
  • starts_after (integer, Unix timestamp) Return events that start after this timestamp.
  • ends_before (integer, Unix timestamp) Return events that end before this timestamp.
  • ends_after (integer, Unix timestamp) Return events that end after this timestamp.
  • expand_recurring (Boolean) If set to true, expands recurring events into individual event instances.
  • show_cancelled (Boolean) If set to true, also show cancelled events.

For example, the following will limit the number of results to 3.

GET https://api.nylas.com/n/<namespace_id>/events?limit=3

Recurring events

If requesting recurring events without expand_recurring, we will only return the ‘master’ recurring event, and only if it falls within the requested time range. recurrence contains recurrence info in RRULE form; this tool is helpful in understanding the RRULE spec.

For convenience, the expand_recurring option will include single instances of a recurring event that fall within the requested time range. These look and behave just like non-recurring events. We recommend using a specific time range with this option.

GET https://api.nylas.com/n/<namespace_id>/events?expand_recurring=true

Currently, these instances of recurring events are read-only.

If the recurring event has individual modifications (overrides), such as a one-off time change, we will return these as individual events regardless of whether expand_recurring is set or not.

If expand_recurring is not set, we will return one-off cancellations as well as the base event, so that clients can accurately expand the recurrence. A cancellation has the field cancelled set to true.

Adding a new event

New events can easily be created with the following API. They are automatically synced back to the provider (e.g., Google Calendar, Microsoft Exchange).

Note that timestamps are expected to be in UTC timezone.

POST https://api.nylas.com/n/<namespace_id>/events

Sample post body

{
    "title":"Friday meeting",
    "when" : {
        "start_time": 1407542195,
        "end_time": 1407543195
    },
    "location": "Nylas HQ",
    "calendar_id": "ci0k1wfyv533ccgox4t7uri4h",
    "participants": [
        {
            "email": "example@gmail.com",
            "name": "Ben Bitdiddle"
        }
    ]
}

Note that if the calendar_id parameter is not provided, then the event will be added to the default calendar.

Updating / Deleting an existing event

Updating and deleting an event is managed in a similar fashion to other endpoints with the restriction that read_only events cannot be updated and events cannot be updated or deleted from a read_only calendar.

PUT https://api.nylas.com/n/<namespace_id>/events/<event_id>

Sample post body

{
    "location": "Atlas Cafe (updated)",
    "calendar_id": "ci0k1wfyv533ccgox4t7uri4h",
    "participants": [
        {
            "email": "example@gmail.com",
            "name": "Ben Bitdiddle"
        },
        {
            "email": "example2@gmail.com",
            "name": "Alyssa P. Hacker"
        },

    ]
}

In the above example, the location of the event is updated and an additional participant is added.

When

The when field on an event can take on one of four forms (described below). Each of these sub-objects contains fields that are either times represented as a unix timestamp in the UTC timezone or dates represented in ISO 8601 format (YYYY-MM-DD).

  • time For a given moment in time which has a time field.
  • timespan For a span of time which has a start_time and end_time field.
  • date For an event on a single day (e.g. a Birthday) which has a date field.
  • datespan For an event spanning multiple days which has a start_date and end_date field.

For example:

American Declaration of Independence:

{
    "object": "date",
    "date": "1776-07-04"
}

Alan Turing’s lifespan would be represented with the following object:

{
    "object": "datespan",
    "start_date": "1912-06-23",
    "end_date": "1954-06-07"
}

The 2014 San Francisco earthquake:

{
    "object": "time",
    "time": 1408875644
}

The last NylasHQ Monday meeting:

{
    "object": "time",
    "start_time": 1409594400,
    "end_time": 1409598000
}

Contacts

The Nylas API provides access to the user’s contacts, making it easy to add contact autocomplete, address book integration, and more to your application. Note that contacts are current read-only.

Retrieving contacts

GET https://api.nylas.com/n/<namespace_id>/contacts

Fetch the user’s contact list. Note This API supports query parameters which make it easy to search the user’s contacts. Available query parameters are listed below:

Options:

  • filter - If given, only return results containing this parameter as a substring of the contact’s name or email address.
  • limit - Maximum number of results to return. Defaults to 100. If limit is set too high, a request may fail with HTTP status code 400 to prevent excessively large response bodies.
  • offset - Zero-based offset to be used with limit for pagination of results.

Sample Response:

[
    {
        "name": "Ben Bitdiddle",
        "email": "ben.bitdiddle@mit.edu",
        "id": "8pjz8oj4hkfwgtb46furlh77",
        "namespace_id": "aqau8ta87ndh6cwv0o3ajfoo2",
        "object": "contact"
    },
    ....
]

Retrieving a single contact

GET https://api.nylas.com/n/<namespace_id>/contacts/<contact_id>

This endpoint retrieves details about a specific contact.

Sample response:

{
    "name": "Ben Bitdiddle",
    "email": "ben.bitdiddle@mit.edu",
    "id": "8pjz8oj4hkfwgtb46furlh77",
    "namespace_id": "aqau8ta87ndh6cwv0o3ajfoo2",
    "object": "contact"
}

Filters

Filters allow you to query mail data based on specific parameters. The more specific you can make the requests the faster they perform, so it’s important to use filters whenever possible. Filters can be appended to API requests on Messages and Threads. Note that values must use percent-encoding (also known as URL encoding).

  • subject Return messages or threads with a given subject string.

  • any_email Return messages or threads that contain the given address in any of the from, to, cc or bcc fields.

  • to Return messages or threads sent to the given address.

  • from Return messages or threads from the given address.

  • cc Return messages or threads cc’d to the given address (by anyone, not just the account holder).

  • bcc Return messages or threads bcc’d to the given address (likely by you, since that header is removed by SMTP gateways)

  • tag Return messages or threads with the given tag. The value can be the name or ID of a user-created tag, a provider-specific label for a folder (gmail-climbing), or one of Nylas’s canonical symbolic tag names (unread, starred, etc.) See Tags for more details.

  • filename Return messages or threads that have a file with the given name attached.

  • limit (integer) The maximum number of results to return. Defaults to 100 for performance. If limit is set too high, a request may fail with HTTP status code 400 to prevent excessively large response bodies.

  • offset (integer) Zero-based offset; use with limit for pagination of results.

Additional Message Filters
  • thread_id Return messages on the thread with the given id.
Additional Thread Filters
  • last_message_before (integer, Unix timestamp) Return threads whose most recent message was received before this timestamp.

  • last_message_after (integer, Unix timestamp) Return threads whose most recent message was received after this timestamp.

  • started_before (integer, Unix timestamp) Return threads whose first message was received before this timestamp.

  • started_after (integer, Unix timestamp) Return threads whose first message was received after this timestamp.

The filters API is not intended to be a replacement for full search functionality. We are working on a dedicated search API for freeform queries of mail data that you can use to perform high performance, full-text search in your application. We’d love to hear your use-cases.

Wildcards & Multiple Value Support

Filters do not currently support wildcards, such as from=*@expedia.com. Support for wildcards on specific filters may be added in the future, and we encourage you to submit pull requests for additional filter functionality you would find useful. Providing multiple values for a single filter, such as tag=unread AND inbox is also unsupported.

Examples

Threads

List threads with the inbox tag:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=inbox

List threads with a user-created tag using the tag ID:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=aqb0llc2ioo0bclh7uxkim9z6

List the 5 most recent unread threads:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=unread&limit=5

List threads that include mark@nylas.com as a participant and are unread, ordered by date:

GET https://api.nylas.com/n/<namespace_id>/threads?tag=unread&any_email=mark@nylas.com

Messages

List messages in a particular thread:

GET https://api.nylas.com/n/<namespace_id>/messages?thread_id=aqb0llc2ioo0bclh7uxkim9z6

List messages from no-reply@asana.com:

GET https://api.nylas.com/n/<namespace_id>/messages?from=no-reply@asana.com

List messages that have an attachment named image.jpg:

GET https://api.nylas.com/n/<namespace_id>/messages?filename=image.jpg

Views

Instead of returning all data about an object, the following views allow you to customize the response for any endpoint. They can be combined with filters.

  • count Return the number of objects in the collection being queried.

  • ids Return only the IDs of objects.

Examples

Count:

GET https://api.inboxapp.com/n/<namespace_id>/threads?tag=inbox&view=count

Response

{
    "count": 386
}

IDs:

GET https://api.inboxapp.com/n/<namespace_id>/messages?thread_id=aqb0llc2ioo0bclh7uxkim9z6&view=ids

Response

[
   "f594seo6izjks2s7qxjbwquol",
   "3a95fq0askqgj7mnh6i281ahz",
   "4vfg8p1om177q2cfx9sselkea"
]

Expanded:

Expands threads response to contain message/drafts sub-objects. Adding view=expanded will remove message_ids and draft_ids, and messages and drafts. Note the message and draft sub-objects do not include body parameter.

GET https://api.inboxapp.com/n/<namespace_id>/threads/<thread_id>?view=count

Response

**Sample response:**

:::json
{
“id”: “evh5uy0shhpm5d0le89goor17”,
“object”: “thread”,
“namespace_id”: “awa6ltos76vz5hvphkp8k17nt”,
“subject”: “Dinner Party on Friday”,
“last_message_timestamp”: 1398229259,
“first_message_timestamp”: 1298229259,
“participants”: [
{
“name”: “Ben Bitdiddle”,
“email”: “ben.bitdiddle@gmail.com”
},
{
“name”: “Charles Mason”,
“email”: “cmason@cmu.edu”
},
{
“name”: “Bill Rogers”,
“email”: “wrogers@mit.edu”
}
],
“snippet”: “Hey Bill, Looking forward to getting together for dinner on Friday. What can I bring? I have a couple bottles of wine or could put together”,
“tags”: [
{
“name”: “inbox”,
“id”: “f0idlvozkrpj3ihxze7obpivh”
},
{
“name”: “unread”,
“id”: “8keda28h8ijj2nogpj83yjep8”
}
],
“messages”: [
“id”: “251r594smznew6yhiocht2v29”,
“object”: “message”,
“subject”: “Dinner on Friday?”,
“from”: [
{
“name”: “Ben Bitdiddle”,
“email”: “ben.bitdiddle@gmail.com”
}
],
“to”: [
{
“name”: “Bill Rogers”,
“email”: “wbrogers@mit.edu”
}
],
“cc”: [],
“bcc”: [],
“date”: 1370084645,
“thread_id”: “5vryyrki4fqt7am31uso27t3f”,
“files”: [],
“snippet”: “Hey Bill, Looking forward to getting together for dinner on Friday. What can I bring? I have a couple bottles of wine or could put together”,
“unread”: false
],
“drafts”: [
“id”: “251r594smznew6yhi12312saq”,
“object”: “draft”,
“subject”: “Re: Dinner on Friday?”,
“from”: [
{
“name”: “Bill Rogers”,
“email”: “wbrogers@mit.edu”
}
],
“to”: [
{
“name”: “Ben Bitdiddle”,
“email”: “ben.bitdiddle@gmail.com”
}
],
“cc”: [],
“bcc”: [],
“date”: 1370084645,
“thread_id”: “5vryyrki4fqt7am31uso27t3f”,
“files”: [
{
“content_type”: “image/jpeg”,
“filename”: “walter.jpg”,
“id”: “7jm8bplrg5tx0c7pon56tx30r”,
“size”: 38633,
“content_id”: “ii_i2cg7byn1_1499bfd99727e569”
}
],
“snippet”: “Sounds good–that bottle of Pinot should go well with the meal. I’ll also bring a surprise for dessert. :) Do you have ice cream? Looking fo”,
“unread”: false
]
}

Errors

Nylas uses conventional HTTP response codes to indicate the success or failure of an API request.

Code Description
200 OK – Everything worked as expected.
400 Bad Request – Missing a required parameter.
401 Unauthorized – No valid API key provided.
402 Request Failed – Parameters were valid but the request failed.
404 Not Found – The requested item doesn’t exist.
429 Too Many Requests.
500, 502,
503, 504
Server errors – An error occured in the Nylas server.

For a full list of possible codes, we recommend the Wikipedia article.

Error bodies includes a JSON object with a standard set of attributes, including an error_type and a human-readable message string. These are designed to make debugging easier and allow for different handling of scenarios that produce the same HTTP status code.

Deltas

The Nylas Sync Engine builds a transaction log that records every change as it sychronizes your users’ mailboxes. Your application can use these changes, exposed through the Delta endpoint, to build email applications that process new data quickly without fetching an index of the user’s mailbox or performing a large number of API calls.

To use the Delta API, your application needs to maintain a sync cursor,
a record of the last change you successfully processed. Each time you perform a
sync, you process the deltas provided by the API and update your stored cursor.

Obtaining a Delta Cursor

The first time you sync using the Delta API, you need to obtain a cursor. The generate_cursor API allows you to exchange a unix timestamp for a cursor so you can begin a sync at an arbitrary point in the user’s mailbox history. Alternatively, if you want to start consuming the user’s entire mailbox history you can set your cursor to 0.

Once you have a cursor, you should store it and update it as you make sync requests.

POST https://api.nylas.com/n/<namespace_id>/delta/generate_cursor
{
    "start": 1401132646
}

Sample response:

{
   "cursor": "aqb0llc2ioo0bclh7uxkim9z6"
}

Requesting a Delta

Each time your application syncs with Nylas, you provide the cursor indicating
your position in the user’s mailbox history. The API request below returns a
set of JSON objects representing individual changes to the user’s mailbox: tag
changes, new messages, etc.

GET https://api.nylas.com/n/<namespace_id>/delta?cursor=<cursor>

Sample response:

{
    "cursor_start": "aqb0llc2ioo0bclh7uxkim9z6",
    "cursor_end": "5u9kwbgyq8wgq0iqdakqt7kjl",
    "deltas": [
        {
            "object_id": "aqb0llc2ioo0bclh7uxkim9z6",
            "event": "modify",
            "type": "thread",
            "cursor": "7ciyf89wprvvkw3p9oz86swcs",
            "attributes": {
                "draft_ids": [
                    "diu1tytx7p9wnx64hdbxsypqe"
                ],
                "first_message_timestamp": 1414778436,
                "id": "71ormxuivtg52p141tpgjk3vi",
                "last_message_timestamp": 1414778436,
                "message_ids": [],
                "namespace_id": "f3b0j663wmm2bluq77uc4db9m",
                "object": "thread",
                "participants": [],
                "snippet": "",
                "subject": "Hello World!",
                "tags": [
                    {
                        "id": "drafts",
                        "name": "drafts"
                    },
                    {
                        "id": "starred",
                        "name": "starred"
                    }
                ]
            }
        },
        {
            "id": "2fhs446h1uiomjg2sa7r5n1w6",
            "event": "create",
            "type": "thread",
            "cursor": "9vsuralamrmitihpf2zszmpmd",
            "attributes": {
                "id": "2fhs446h1uiomjg2sa7r5n1w6",
                "last_message_timestamp": 1401132649,
                "message_ids": [
                    "ebszclpialarlf32m1hxdcckk",
                    "duknijxbjxtonwi59p7wd17ew",
                    "e89w5zrh5o7oklc8cp9vjup69"
                ],
                "namespace_id": "ebaa9877yhmaeamqodbmq7rqa",
                "object": "thread",
                "participants": [
                    {
                        "email": "zulip@zulip.com",
                        "name": "Michael Grinich"
                    },
                    {
                        "email": "ben@nylas.com",
                        "name": ""
                    }
                ],
                "subject": "Missed Zulip from Michael Grinich",
                "first_message_timestamp": 1401132649
            }
        },
        {
            "cursor": "9vsuralamrmitihpf2zszmpmd",
            "event": "delete",
            "id": "5oly0nmkfbgnjhw00xa4i0k5l",
            "object": "tag"
        }
    ]
}

Each element of the response contains the following fields:

  • "cursor": The cursor value for this delta.
  • "object": The type of the changed object, e.g., “message” or “thread“.
  • "id": The id of the changed object.
  • "event": The type of change, either "create", "modify" or "delete".
  • "attributes": The state of the object when the delta was generated.

After you’ve processed the deltas, your application should update its stored
cursor to the value of cursor_end in the response. Nylas may only return the first batch of changes, so it’s important to make this API call repeatedly until you receive the same cursor_end that you sent (cursor_start). This indicates that you have consumed the entire transaction log of the user’s mailbox and your application is up-to-date.

Streaming Delta Updates

The streaming endpoint allows you to get changes in real time, without needing to repeatedly poll. First obtain a delta cursor as described above, and then use it to query the /delta/streaming endpoint:

GET https://api.nylas.com/n/<namespace_id>/delta/streaming?cursor=<cursor>

This will start a long-polling HTTP connection. The server will stream deltas
starting from that cursor, but then keep the connection open and continue to
stream new changes.

Each change event has the same format as a single delta above:

{
    "cursor": "9vsuralamrmitihpf2zszmpmd",
    "event": "delete",
    "id": "5oly0nmkfbgnjhw00xa4i0k5l",
    "object": "tag"
}

If the connection is interrupted or your client goes offline, you can issue
a new query, passing the cursor for the last delta you processed. This ensures
that you don’t miss any changes.

Getting a subset of all changes

If you don’t want to get changes for all the API object types, you can pass an
additional parameter exclude_types in your request to the /delta or
delta/streaming endpoint. The response won’t contain any change events for
objects of the types that you specify. For example, if your application doesn’t
need to know about changes to contacts or calendar events, you can make the
request

GET
https://api.nylas.com/n/<namespace_id>/delta/streaming?cursor=<cursor>&exclude_types=message,contact

The value of exclude_types must be a comma-separated list whose elements are
any of contact, event, file, message, tag, thread.