Create grants with IMAP authentication
This page explains how to authenticate end users to your Nylas application using IMAP auth.
IMAP connections don’t require a provider auth app, and they don’t include calendar functionality.
New options for Yahoo, Exchange, and iCloud users
If you are authenticating Yahoo, Exchange on-prem, or iCloud users, you can either connect them using IMAP, or use the dedicated connectors for those providers. If you connect using IMAP, you can only access email data from the provider, even if the service also provides calendar features.
If you authenticate Yahoo users, you should implement the new v3 Yahoo OAuth method instead of IMAP authentication to improve reliability.
Create a connector
Create a connector by making a call to POST /v3/connectors and setting the provider to imap.
{ "name": "Staging App 1", "provider": "imap"}You can also create a connector using the Nylas SDKs, as in the following examples.
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: { name: 'aol', provider: 'imap', } })
console.log('Connector created:', connector) } catch (error) { console.error('Error creating connector:', error) }}
createConnector()from dotenv import load_dotenvload_dotenv()
import osimport sysfrom nylas import Client
nylas = Client( os.environ.get('NYLAS_API_KEY'), os.environ.get('NYLAS_API_URI'))
connector = nylas.connectors.create( request_body={ "name": "aol", "provider": "imap" })require 'nylas'
nylas = Nylas::Client.new(api_key: "<NYLAS_API_KEY>")
request_body = { name: "aol", provider: "imap",}
connector = nylas.connectors.create(request_body: request_body)
puts connectorimport 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.NylasClientimport 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
Nylas v3 offers Hosted OAuth and Custom authentication for the supported IMAP providers.
Hosted OAuth
You can create grants with Hosted OAuth. Learn more about creating grants with Hosted Oauth and an API key and 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 authenticationapp.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 toapp.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_dotenvload_dotenv()
import jsonimport os
from functools import wrapsfrom io import BytesIOfrom flask import Flask, request, redirect, gfrom 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 urlend
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}" endendimport 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.NylasClientimport com.nylas.models.AccessTypeimport com.nylas.models.AuthProviderimport com.nylas.models.Promptimport com.nylas.models.UrlForAuthenticationConfigimport spark.kotlin.Httpimport 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 }}Custom authentication
You can create grants with Custom authentication (POST /v3/connect/custom) if you already have a password or app password for the end user.
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.
Static IP support for IMAP accounts
Some email servers in secure environments only accept connections and data from a known list of sender IP addresses. If you need to connect to a server with these settings, you can add static IP support to your Nylas plan.
When you add static IP support to your plan, Nylas uses only a specific set of static IPs when connecting your application’s users. You can then provide the administrators of those email servers with an allowlist of Nylas IPs so the user can authenticate with that server.
Static IP support is currently available for IMAP. Support for Exchange on-premises servers is coming soon.
To add static IP support to your Nylas account, contact your account representative or Nylas support.
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_uriwith the error code instead of showing an error message.
What’s next?
Now that you have an IMAP connector and a grant, you can…
- Manage your connectors (previously called “integrations”).
- Manage your grants.
- Review Nylas’ event codes.