This guide is for AI coding agents (Claude Code, Cursor, GitHub Copilot, Windsurf) helping developers build SaaS applications with the Nylas APIs. Follow the steps below — do as much as you can yourself, and only ask the developer when you hit a step that requires a browser.
If you are an autonomous AI agent that needs direct email and calendar access (like OpenClaw or a custom LLM agent), see Quickstart: AI agents instead.
Rules for coding agents
Section titled “Rules for coding agents”- Always use Nylas v3. The v2 API is deprecated. v2 code uses
access_tokenandclient_secret; v3 usesapi_keyandgrant_id. If you see v2 patterns in your training data, do not use them. - Use the SDK for Node.js, Python, Ruby, and Java/Kotlin. Only use raw HTTP calls for languages without an SDK.
- Never hardcode API keys. Use environment variables (
NYLAS_API_KEY) and.envfiles excluded from version control. - Never expose the API key in client-side code. All Nylas API calls must happen server-side.
- Set
NYLAS_API_URIfor EU deployments. It defaults tohttps://api.us.nylas.com. EU applications must usehttps://api.eu.nylas.com. - Handle pagination. List endpoints return a
next_cursorfield. Use it to fetch subsequent pages. - Use webhooks for real-time updates instead of polling. See the webhooks documentation.
How Nylas works (the short version)
Section titled “How Nylas works (the short version)”Nylas is a unified API that sits between your application and email providers (Gmail, Microsoft, Yahoo, iCloud, IMAP, Exchange). You write code against one API; Nylas handles the provider differences.
Three things matter:
- API key — authenticates your application. Pass it as a Bearer token. The developer gets this from the Nylas Dashboard or the CLI.
- Grant ID — identifies which user’s mailbox to operate on. One grant = one connected email account. You get a grant ID when a user authenticates through Nylas OAuth.
- Base URL —
https://api.us.nylas.com(US) orhttps://api.eu.nylas.com(EU). All endpoints are prefixed with/v3/.
Every API call follows the pattern: {base_url}/v3/grants/{grant_id}/{resource} with the API key in the Authorization: Bearer header.
Errors always return this JSON shape:
{ "request_id": "5fa64c92-e840-4357-86b9-2aa364d35b88", "error": { "type": "unauthorized", "message": "Unauthorized" }}Common error.type values: unauthorized (bad/expired key), not_found_error (invalid ID or grant), invalid_request_error (bad parameters), rate_limit_error (slow down), insufficient_scopes (missing provider permissions).
Step 1: Check if the developer has credentials
Section titled “Step 1: Check if the developer has credentials”First, check if the CLI is already installed and configured (the developer may have run nylas init previously):
nylas auth whoami --jsonIf this returns valid JSON with status: "valid", credentials exist on this machine. Extract them, write the .env, and skip to Step 3:
echo "NYLAS_API_KEY=$(nylas auth token)" >> .envecho "NYLAS_GRANT_ID=$(nylas auth whoami --json | jq -r .grant_id)" >> .envIf jq is not available, run nylas auth whoami --json and nylas auth token separately and parse the output yourself.
If nylas is not found, or whoami returns an error, check for an environment variable:
echo $NYLAS_API_KEYIf set, skip to Step 3. If not, continue to Step 2.
Step 2: Provision credentials with the CLI
Section titled “Step 2: Provision credentials with the CLI”Install the Nylas CLI yourself:
brew install nylas/nylas-cli/nylasIf Homebrew is not available:
curl -fsSL https://cli.nylas.com/install.sh | bashNow check if the developer has already run setup:
nylas auth whoami --jsonIf this returns valid JSON with email, grant_id, and status: "valid", credentials already exist. Extract them:
nylas auth tokenThis prints the raw API key as a plain string. Extract both values and add them to the project’s .env file:
# Add to .env (create if needed, ensure .env is in .gitignore)echo "NYLAS_API_KEY=$(nylas auth token)" >> .envecho "NYLAS_GRANT_ID=$(nylas auth whoami --json | jq -r .grant_id)" >> .envIf jq is not available, run nylas auth whoami --json and nylas auth token separately and parse the output yourself.
If nylas auth whoami fails (no credentials), ask the developer to run one command. This is the only step that requires a human — it opens a browser for account creation and SSO:
Run
nylas initin your terminal. It will open a browser to create your Nylas account and connect an email. Once you’re done, I’ll extract the credentials and set up the project.
After the developer confirms, extract credentials as shown above.
Step 3: Install the SDK
Section titled “Step 3: Install the SDK”npm install nylaspip install nylasgem install nylasimplementation 'com.nylas:nylas:2.+'Step 4: Working example
Section titled “Step 4: Working example”This example initializes the SDK, lists messages, and sends an email.
import Nylas from "nylas";
// Initialize — apiUri defaults to https://api.us.nylas.com// Set NYLAS_API_URI for EU deploymentsconst nylas = new Nylas({ apiKey: process.env.NYLAS_API_KEY, apiUri: process.env.NYLAS_API_URI || "https://api.us.nylas.com",});
const grantId = process.env.NYLAS_GRANT_ID;
// List the 5 most recent messagesconst messages = await nylas.messages.list({ identifier: grantId, queryParams: { limit: 5 },});
for (const msg of messages.data) { console.log(`${msg.subject} — from ${msg.from?.[0]?.email}`);}
// Send an emailconst sent = await nylas.messages.send({ identifier: grantId, requestBody: { subject: "Hello from Nylas", body: "This email was sent using the Nylas Node.js SDK.", },});
console.log(`Sent message ID: ${sent.data.id}`);import osfrom nylas import Client
# Initialize — pass api_uri for EU deploymentsnylas = Client( os.environ["NYLAS_API_KEY"], os.environ.get("NYLAS_API_URI", "https://api.us.nylas.com"),)
grant_id = os.environ["NYLAS_GRANT_ID"]
# List the 5 most recent messagesmessages = nylas.messages.list( grant_id, query_params={"limit": 5},)
for msg in messages.data: print(f"{msg.subject} — from {msg.from_[0].email}")
# Send an emailsent = nylas.messages.send( grant_id, request_body={ "subject": "Hello from Nylas", "body": "This email was sent using the Nylas Python SDK.", },)
print(f"Sent message ID: {sent.data.id}")# List messages (replace <NYLAS_GRANT_ID> and <NYLAS_API_KEY>)curl -X GET "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages?limit=5" \ -H "Authorization: Bearer <NYLAS_API_KEY>" \ -H "Content-Type: application/json"
# Send an emailcurl -X POST "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send" \ -H "Authorization: Bearer <NYLAS_API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "to": [{"name": "Alice", "email": "[email protected]"}], "subject": "Hello from Nylas", "body": "This email was sent using the Nylas API." }'List messages returns a paginated response:
{ "request_id": "d0c951b9-61db-4daa-ab19-cd44afeeabac", "data": [ { "id": "5d3qmne77v32r8l4phyuksl2x", "grant_id": "1", "subject": "Learn how to Send Email with Nylas APIs", "snippet": "Send Email with Nylas APIs", "body": "Learn how to send emails using the Nylas APIs!", "date": 1706811644, "unread": true, "starred": false, "folders": ["UNREAD", "CATEGORY_PERSONAL", "INBOX"], "thread_id": "1" } ], "next_cursor": "123"}{ "request_id": "1", "data": { "id": "1", "grant_id": "1", "subject": "Hello from Nylas", "body": "This email was sent using the Nylas API.", "date": 1707839231, "thread_id": "2" }}Authenticate users in your application
Section titled “Authenticate users in your application”The example above uses a grant ID from the CLI (your developer’s own account). In a real SaaS application, you need to let users connect their own email accounts through OAuth:
- Your app calls the SDK to generate an auth URL
- The user clicks the link and authenticates with their email provider
- Nylas redirects back to your app with a code
- Your app exchanges the code for a grant ID
- You store the grant ID and use it for that user’s API calls
See the Hosted OAuth quickstart for the complete implementation with code samples.
Manage the grant lifecycle
Section titled “Manage the grant lifecycle”Grants can expire when a user revokes access, changes their password, or when a provider token expires. Your application needs to handle this:
- Detect expired grants by checking for
401errors on API calls or listening for thegrant.expiredwebhook event. - Re-authenticate by redirecting the user through the OAuth flow again. This refreshes the grant without losing data — do not delete and recreate.
- Never delete a grant to fix an auth error. Deleting a grant permanently removes all synced data. Re-authentication preserves it.
For the full guide on grant states, expiry detection, and re-authentication flows, see Handling expired grants. For managing grants at scale, see Managing grants.
Go deeper
Section titled “Go deeper”When you need more detail, use these machine-readable sources instead of guessing:
# Curated sitemap with agent instructions (start here)curl https://developer.nylas.com/llms.txt
# Full documentation in one file (broad context)curl https://developer.nylas.com/llms-full.txt
# Any single page as clean markdown (specific lookups)curl -H "Accept: text/markdown" https://developer.nylas.com/docs/v3/email/The Accept: text/markdown header works on every page and returns an x-markdown-tokens header with the estimated token count.
| What you need | Where to find it |
|---|---|
| Full email API (threads, drafts, attachments, folders) | Email documentation |
| Calendar API (events, availability, scheduling) | Calendar documentation |
| Contacts API | Contacts documentation |
| OAuth and authentication | Authentication guide |
| Grant lifecycle (expiry, re-auth, deletion) | Handling expired grants |
| Managing grants at scale | Managing grants |
| Webhooks for real-time notifications | Notifications documentation |
| Interactive API reference (try endpoints in-browser) | API reference |
| Provider-specific guides (Gmail, Microsoft, etc.) | Provider guides |
| Detailed LLM prompts for building Nylas features | AI prompts quickstart |
| Nylas CLI (provisioning, testing, debugging) | GitHub / Guides |
| Node.js SDK | SDK documentation |
| Python SDK | SDK documentation |
| Ruby SDK | SDK documentation |
| Java/Kotlin SDK | SDK documentation |