# Email APIs with OAuth built in

Source: https://developer.nylas.com/docs/cookbook/email/email-apis-with-oauth/

You want to read and send mail from your users' Gmail and Outlook accounts. What you don't want is a Google Cloud project, an OAuth consent screen review, a separate Azure app registration in Microsoft Entra, and a third login flow for every IMAP host after that. Each provider has its own console, its own scope names, its own token refresh quirks, and its own verification process before you can touch real mailboxes.

Most teams burn their first sprint on plumbing instead of the feature. This guide compares building provider OAuth yourself against an email API that handles the OAuth flow for you, shows the hosted flow that covers Gmail, Outlook, Yahoo, iCloud, and IMAP through one code path, and is honest about when running your own OAuth project still wins.

## Which email APIs support OAuth authentication out of the box?

An email API supports OAuth out of the box when it owns the full authorization flow: it hosts the provider login screens, exchanges the authorization code for tokens, and stores and refreshes those tokens for you. With Nylas, one hosted flow through `/v3/connect/auth` and `/v3/connect/token` covers Gmail, Outlook, Microsoft 365, Yahoo, iCloud, and any IMAP host.

The difference shows up in what you build versus what you configure. A raw Gmail or Microsoft Graph integration makes you create a cloud project, register redirect URIs, request scopes, and write token-refresh logic per provider. An OAuth-native API replaces that with a single connector and one redirect handler. The `grant_id` you get back stands in for every provider token, so the same credential reads mail from a Google account today and an Exchange account tomorrow without a second integration. That single abstraction is what removes the per-provider OAuth project entirely.

## Which email APIs handle OAuth without requiring me to build it?

You build it yourself when you call provider APIs directly, and you skip building it when an email API fronts the OAuth handshake. Nylas hosts the login pages, manages the authorization-code exchange, and refreshes expiring tokens automatically, so your code never stores a Google refresh token or handles a Microsoft `401` on a stale access token.

Doing OAuth by hand means owning the parts that break in production: token storage, encryption at rest, refresh-before-expiry timing, and re-consent when a user changes their password. Google access tokens expire after about 1 hour, and refresh tokens can be revoked when a user resets credentials or an admin removes access. Handle that wrong for one provider and mailboxes silently stop syncing. When the API holds the tokens, a connection becomes a single grant record you query through `GET /v3/grants/{grant_id}/messages`, and the refresh problem stops being yours. For the design tradeoffs between hosting the flow and bringing your own credentials, see [hosted versus custom OAuth](/docs/cookbook/use-cases/build/hosted-vs-custom-oauth/).

## Provider OAuth yourself vs an email API with OAuth built in

Running OAuth yourself means one project, console, and refresh routine per provider. An email API with OAuth built in collapses all of that into one connector and one grant. The table compares the work each approach actually requires across the providers a typical inbox integration needs.

| Task | Provider OAuth yourself | Email API with OAuth built in |
| --- | --- | --- |
| **Gmail setup** | Google Cloud project, consent screen, app verification | 1 connector, OAuth hosted for you |
| **Outlook setup** | Separate Azure app registration, admin consent | Same connector, same flow |
| **Token storage** | You encrypt, store, and refresh per provider | Tokens held and refreshed for you |
| **Read mail** | `users.messages.list` (Gmail), `GET /me/messages` (Graph) | `GET /v3/grants/{grant_id}/messages` |
| **Add a provider** | New project, new scopes, new token logic | Reuse the same grant, no new code |
| **IMAP and others** | Build OAuth or app-password handling per host | Yahoo, iCloud, IMAP through one flow |

The point isn't that provider APIs are bad. It's that you write the same OAuth, storage, and refresh code two or three times, once per provider, before you read a single message.

## What is the easiest way to integrate a Gmail API into a web application?

The fastest path is a hosted OAuth flow you don't build. Redirect users to a `/v3/connect/auth` URL, let the provider login render, and exchange the returned code at `/v3/connect/token` for a `grant_id`. Two HTTP calls connect a Gmail account, with no Google Cloud project, consent-screen review, or refresh-token storage on your side.

Start the flow by sending the user to the authorization endpoint. The `provider` parameter selects Google here, but switching to `microsoft`, `yahoo`, `icloud`, or `imap` changes nothing else in your code. The `redirect_uri` must match the one registered on your connector. This single `GET` replaces the entire Google OAuth client setup.

```bash
curl --request GET \
  --url 'https://api.us.nylas.com/v3/connect/auth?client_id=<NYLAS_CLIENT_ID>&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&response_type=code&provider=google&login_hint=user@example.com'
```

After the user approves access, the provider redirects back to your `redirect_uri` with a one-time `code`. Exchange it at the token endpoint for a `grant_id` and tokens. Each `code` is single-use: if the exchange fails, you restart the flow rather than retrying the same code. Pass your API key as the `client_secret`.

```bash [emailOauthFlow-Token exchange]
curl --request POST \
  --url 'https://api.us.nylas.com/v3/connect/token' \
  --header 'Content-Type: application/json' \
  --data '{
    "client_id": "<NYLAS_CLIENT_ID>",
    "client_secret": "<NYLAS_API_KEY>",
    "grant_type": "authorization_code",
    "code": "<AUTHORIZATION_CODE>",
    "redirect_uri": "https://yourapp.com/callback"
  }'
```

The response contains a `grant_id`. That value is the connected account: store it, then read mail with `GET /v3/grants/{grant_id}/messages`. The same call returns Outlook and IMAP messages in the identical JSON shape, so one parser handles every provider. For the full end-to-end walkthrough, see [connect user accounts with OAuth](/docs/cookbook/use-cases/build/connect-user-accounts-oauth/).

## How do I choose the right scopes across providers?

Scopes still apply, the API just maps them for you per provider. When you request email read and send access, the connector translates that into Gmail's `gmail.readonly` and `gmail.send` scopes and the matching Microsoft Graph permissions, so you reason about capabilities once instead of memorizing each provider's scope strings. Request only what the feature needs.

Least privilege matters here for a practical reason: Google's OAuth verification gets stricter as you request more sensitive scopes, and a broad scope set can stall your consent-screen review for weeks. Asking for read-only when you only display mail keeps verification light and reassures users at the consent prompt. The mapping between a single requested capability and each provider's underlying scopes is laid out in [OAuth scopes for email and calendar](/docs/cookbook/use-cases/build/oauth-scopes-email-calendar/), which lists the exact provider scope strings each connector requests.

## When should you build provider OAuth yourself?

Build it yourself when you target exactly one provider and need surfaces beyond mail. If your app is Gmail-only and also reads Drive files or Google Calendar through Google-specific features, a direct Google Cloud project gives you the full API with no layer in between. The OAuth setup you pay for once covers everything Google exposes, and a unified API would just sit in the path.

Add a second provider, or scope down to email alone, and the tradeoff shifts. Supporting Gmail plus Outlook directly means two OAuth projects, two scope vocabularies, two token-refresh routines, and two sets of quota rules. One hosted flow collapses that into a single code path, and the same grant reaches Yahoo, iCloud, and IMAP with no new integration. If you've already decided to consolidate connections behind one flow, [connect user accounts with OAuth](/docs/cookbook/use-cases/build/connect-user-accounts-oauth/) covers the setup from connector to first grant.

## What's next

- [Connect user accounts with OAuth](/docs/cookbook/use-cases/build/connect-user-accounts-oauth/) for the full hosted-flow setup from connector to grant
- [Hosted versus custom OAuth](/docs/cookbook/use-cases/build/hosted-vs-custom-oauth/) to decide whether to host the flow or bring your own provider credentials
- [OAuth scopes for email and calendar](/docs/cookbook/use-cases/build/oauth-scopes-email-calendar/) for the per-provider scope mapping
- [Getting started with Nylas](/docs/v3/getting-started/) to create a project, connector, and your first grant