Create grants with IMAP authentication
This page explains how to authenticate users to your Nylas application using IMAP auth. IMAP connections don't require a provider auth app, and they don't include calendar functionality.
For more information about working with IMAP accounts in Nylas v3, see Use IMAP accounts and data with Nylas.
New options for Yahoo, Exchange, and iCloud users
If you're authenticating Yahoo, Exchange on-prem, or iCloud users, you can either connect them using IMAP auth or use the dedicated Nylas connectors for those providers. If you authenticate them using IMAP, you can access email data only, even if the service also provides calendar features.
If you plan to authenticate Yahoo users, you should use the new v3 Yahoo OAuth method instead of IMAP auth to improve reliability.
Create an IMAP connector
🔍 IMAP doesn't support the concept of scopes, so you don't need to list any during the authentication process.
You can create an IMAP connector in the v3 Dashboard, using the Nylas APIs, or using the Nylas SDKs.
Create an IMAP connector in v3 Dashboard
To create an IMAP connector in the Nylas v3 Dashboard, first navigate to the Nylas application you're creating the connector for. Then, click Connectors in the left navigation, find the IMAP tile, and click Add.
Create an IMAP connector using APIs
Make a POST /v3/connectors
request and set provider
to imap
to create an IMAP connector.
curl --request POST \
--url https://api.us.nylas.com/v3/connectors \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, application/gzip' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--data '{
"provider": "imap"
}'
Create an IMAP connector using Nylas SDKs
The following examples show how to create an IMAP connector using the Nylas SDKs.
import 'dotenv/config'
import Nylas from 'nylas'
const config = {
apiKey: process.env.NYLAS_API_KEY,
apiUri: process.env.NYLAS_API_URI,
}
const nylas = new Nylas(config)
async function createConnector() {
try {
const connector = await nylas.connectors.create({
requestBody: {
provider: 'imap'
}
})
console.log('Connector created:', connector)
} catch (error) {
console.error('Error creating connector:', error)
}
}
createConnector()
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')
)
connector = nylas.connectors.create(
request_body={
"provider": "imap"
}
)
require 'nylas'
nylas = Nylas::Client.new(api_key: "<NYLAS_API_KEY>")
request_body = {
provider: "imap"
}
connector = nylas.connectors.create(request_body: request_body)
puts connector
import com.nylas.NylasClient;
import com.nylas.models.*;
public class connector {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
CreateConnectorRequest request = new CreateConnectorRequest.Imap();
nylas.connectors().create(request);
}
}
import com.nylas.NylasClient
import com.nylas.models.CreateConnectorRequest
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = "<NYLAS_API_KEY>")
val request : CreateConnectorRequest = CreateConnectorRequest.Imap();
nylas.connectors().create(request)
}
Create grants for IMAP users
Most IMAP providers require that you use an application password to authenticate third-party tools. If this is the case, you need to redirect the user to their provider so they can enter their app password before authenticating. Some providers use the user's usual login credentials and don't require app passwords.
Nylas v3 offers Hosted OAuth and Custom Authentication for the supported IMAP providers.
🔍 Nylas creates only one grant per email address in each application. If an end user authenticates with your Nylas application using the email address associated with an existing grant, Nylas re-authenticates the grant instead of creating a new one.
Create an IMAP grant with Hosted OAuth
You can create IMAP grants using either Hosted OAuth with an API key or Hosted OAuth and an access token.
You can also start the Hosted Auth flow using the Nylas SDKs, as in the examples below.
import 'dotenv/config'
import express from 'express'
import Nylas from 'nylas'
const config = {
clientId: process.env.NYLAS_CLIENT_ID,
clientSecret: process.env.NYLAS_CLIENT_SECRET,
callbackUri: "http://localhost:3000/oauth/exchange",
apiKey: process.env.NYLAS_API_KEY,
apiUri: process.env.NYLAS_API_URI,
}
const nylas = new Nylas({
apiKey: config.apiKey,
apiUri: config.apiUri
})
const app = express()
const port = 3000
// Route to initialize authentication
app.get('/nylas/auth', (req, res) => {
const authUrl = nylas.auth.urlForOAuth2({
clientId: config.clientId,
provider: 'imap',
redirectUri: config.redirectUri,
loginHint: process.env.AOL_IMAP_USERNAME,
state: "state"
})
res.redirect(authUrl)
})
// Callback route Nylas redirects to
app.get('/oauth/exchange', async (req, res) => {
const code = req.query.code
if (!code) {
res.status(400).send('No authorization code returned from Nylas')
return
}
try {
const response = await nylas.auth.exchangeCodeForToken({
clientId: config.clientId,
redirectUri: config.redirectUri,
code,
})
const { grantId } = response
res.status(200)
} catch (error) {
res.status(500).send('Failed to exchange authorization code for token')
}
})
from dotenv import load_dotenv
load_dotenv()
import json
import os
from functools import wraps
from io import BytesIO
from flask import Flask, request, redirect, g
from nylas import Client
nylas = Client(
os.environ.get("NYLAS_CLIENT_ID"),
os.environ.get("NYLAS_API_URI")
)
REDIRECT_CLIENT_URI = 'http://localhost:9000/oauth/exchange'
flask_app = Flask(__name__)
@flask_app.route("/nylas/generate-auth-url", methods=["GET"])
def build_auth_url():
auth_url = nylas.auth.url_for_oauth2(
config={
"client_id": os.environ.get("NYLAS_CLIENT_ID"),
"provider": 'imap',
"redirect_uri": REDIRECT_CLIENT_URI,
"login_hint": os.environ.get("AOL_IMAP_USERNAME"),
"state": "state",
}
)
return redirect(auth_url)
@flask_app.route("/oauth/exchange", methods=["GET"])
def exchange_code_for_token():
code_exchange_response = nylas.auth.exchange_code_for_token(
request={
"code": request.args.get('code'),
"client_id": os.environ.get("NYLAS_CLIENT_ID"),
"redirect_uri": REDIRECT_CLIENT_URI
}
)
return {
'email': code_exchange_response.email,
'grant_id': code_exchange_response.grant_id
}
# frozen_string_literal: true
require 'nylas'
require 'sinatra'
set :show_exceptions, :after_handler
error 404 do
'No authorization code returned from Nylas'
end
error 500 do
'Failed to exchange authorization code for token'
end
nylas = Nylas::Client.new(api_key: "<NYLAS_API_KEY>")
get '/nylas/auth' do
config = {
client_id: "<NYLAS_CLIENT_ID>",
provider: 'imap',
redirect_uri: 'http://localhost:4567/oauth/exchange',
login_hint: '<AOL_IMAP_USER>',
state: "<state>"
}
url = nylas.auth.url_for_oauth2(config)
redirect url
end
get '/oauth/exchange' do
code = params[:code]
status 404 if code.nil?
begin
response = nylas.auth.exchange_code_for_token({
client_id: "<NYLAS_CLIENT_ID>",
redirect_uri: 'http://localhost:4567/oauth/exchange',
code: code
})
rescue StandardError
status 500
else
puts response
grant_id = response[:grant_id]
email = response[:email]
"Grant_Id: #{grant_id} \n Email: #{email}"
end
end
import java.util.*;
import static spark.Spark.*;
import com.nylas.NylasClient;
import com.nylas.models.*;
public class AuthRequest {
public static void main(String[] args) throws NylasSdkTimeoutError, NylasApiError {
NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();
get("/nylas/auth", (request, response) -> {
List<String> scope = new ArrayList<>();
UrlForAuthenticationConfig config = new UrlForAuthenticationConfig(
"<NYLAS_CLIENT_ID>",
"http://localhost:4567/oauth/exchange",
AccessType.ONLINE,
AuthProvider.IMAP,
Prompt.DETECT,
scope,
true,
"sQ6vFQN",
"example@aol.com");
String url = nylas.auth().urlForOAuth2(config);
response.redirect(url);
return null;
});
get("/oauth/exchange", (request, response) -> {
String code = request.queryParams("code");
if(code == null) { response.status(401);}
assert code != null;
CodeExchangeRequest codeRequest = new CodeExchangeRequest(
"http://localhost:4567/oauth/exchange",
code,
"<NYLAS_CLIENT_ID>",
"nylas");
try {
CodeExchangeResponse codeResponse = nylas.auth().exchangeCodeForToken(codeRequest);
return "%s".formatted(codeResponse);
} catch(Exception e) {
return "%s".formatted(e);
}
});
}
}
import com.nylas.NylasClient
import com.nylas.models.AccessType
import com.nylas.models.AuthProvider
import com.nylas.models.Prompt
import com.nylas.models.UrlForAuthenticationConfig
import spark.kotlin.Http
import spark.kotlin.ignite
fun main(args: Array<String>) {
val nylas: NylasClient = NylasClient(apiKey = "<NYLAS_API_KEY>")
val http: Http = ignite()
http.get("/nylas/auth") {
val scope = listOf("https://www.googleapis.com/auth/userinfo.email")
val config : UrlForAuthenticationConfig = UrlForAuthenticationConfig(
"<NYLAS_CLIENT_ID>",
"http://localhost:4567/oauth/exchange",
AccessType.ONLINE,
AuthProvider.IMAP,
Prompt.DETECT,
scope,
true,
"sQ6vFQN",
"<email_to_connect>")
val url = nylas.auth().urlForOAuth2(config)
response.redirect(url)
}
}
http.get("/oauth/exchange") {
val code : String = request.queryParams("code")
if(code == "") { response.status(401) }
val codeRequest : CodeExchangeRequest = CodeExchangeRequest(
"http://localhost:4567/oauth/exchange",
code,
"<NYLAS_CLIENT_ID>",
"nylas"
)
try {
val codeResponse : CodeExchangeResponse =
nylas.auth().exchangeCodeForToken(codeRequest)
codeResponse
} catch (e : Exception) {
e
}
}
Create an IMAP grant with Custom Authentication
If you already have your user's password or app password, you can create a grant for them using Custom Authentication.
The example below shows how to make a Custom authentication request with the correct provider and settings. The rest of the authentication process follows the same process as for non-IMAP grant creation.
curl -X POST https://api.us.nylas.com/v3/connect/custom \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"provider": "imap",
"settings": {
"imap_username": "<IMAP_USERNAME>",
"imap_password": "<IMAP_PASSWORD>",
"imap_host": "imap.mail.me.com",
"imap_port": 993,
"smtp_host": "smtp.mail.me.com",
"smtp_port": 465
}
}'
For more information, see the Custom auth documentation.
Error handling for IMAP Hosted authentication
Nylas creates a grant only if both the IMAP settings are validated and the provider accepts the end user's login credentials. When an error occurs, the redirect_uri
includes an error_type
query parameter when the auth process is complete. The possible error_type
values are...
provider_not_responding
: The IMAP provider didn't respond to the login request from Nylas.invalid_authentication
: The provider responded with an incorrect credential error. Nylas prompts the user with an error message.auth_limit_reached
: The user entered an incorrect password three times. Nylas redirects back to your application'sredirect_uri
with the error code instead of showing an error message.