Skip to content
Skip to main content

Authenticate from a headless server

Last updated:

A cron job, a worker process, or a virtual machine has no screen and no browser, so it cannot run the interactive consent flow that asks a user to approve access at their provider. When you already hold a provider OAuth refresh token from your own authentication code, you skip the browser entirely and hand that token straight to Nylas to mint a grant. This recipe covers Bring Your Own Authentication, secure secret storage on servers, and refresh token rotation.

This is the no-browser counterpart to OAuth for a desktop email app, which still opens a system browser with PKCE. If your server can redirect a human to a provider login at any point, use the hosted flow in Connect user accounts with OAuth instead.

How do I authenticate without a browser flow?

Section titled “How do I authenticate without a browser flow?”

A headless server authenticates by sending a provider refresh token it already holds to the POST /v3/connect/custom endpoint. Nylas exchanges that token, stores it on a grant, and returns a grant_id you reuse for every request. No redirect, no consent screen, no port to listen on.

This path is called Bring Your Own Authentication. It fits two common situations: you run your own OAuth code and want to migrate users into Nylas, or a backend service obtains tokens through a provider’s service account or device flow and never has a user present. The request carries just 2 fields, the required provider value and a settings object holding the refresh_token. Everything else about the grant, including the connected email address and scopes, is read from the token. Because no human approves anything at request time, the token you supply must already carry the scopes your features need. The Bring Your Own Authentication guide documents the full request shape and the IMAP credential variant.

What does the custom connect response return?

Section titled “What does the custom connect response return?”

The POST /v3/connect/custom call returns a grant object whose id is the grant_id your headless service stores and reuses. The response also reports grant_status, the resolved email, and the scope array derived from the token you supplied, so you can confirm the connection succeeded before any worker runs.

A grant_status of valid means the grant is ready and the underlying token refreshes automatically while you use an API key. The response below is the shape returned for a Microsoft account; the provider and scope values change per provider, but the id field is always the identifier you persist. Store that single value against your user record and discard the raw refresh token from your application memory once Nylas holds it. The Microsoft example below resolves 3 scopes from the supplied token, and each grant maps to exactly one connected account, so a service syncing 500 users holds one grant ID per user. For the field-by-field breakdown, see the Bring Your Own Authentication guide.

Where do I store secrets on a server with no UI?

Section titled “Where do I store secrets on a server with no UI?”

Keep the provider refresh token and your Nylas API key in a dedicated secrets manager, never in a config file, a container image layer, or a checked-in environment file. On a headless host the operating system keychain is unavailable, so the standard answer is a managed secret store such as AWS Secrets Manager, Google Secret Manager, HashiCorp Vault, or Kubernetes Secrets backed by an external provider.

Inject secrets at runtime and hold them in process memory only. A leaked container image or a backup of the host filesystem then exposes nothing reusable, because the secret lives in the manager and not on disk. Grant the worker an identity scoped to read only the keys it needs, which limits blast radius if one service is compromised. Once a grant exists, the most valuable secret to protect is your API key, since a single key authenticates calls across every grant in the project. Many teams rotate that key on a 90 day cycle. See Manage API keys for creating and rotating keys, and the authentication overview for how grants and keys relate.

How do I rotate refresh tokens without downtime?

Section titled “How do I rotate refresh tokens without downtime?”

Once Nylas holds the grant, you do not rotate the provider refresh token yourself. The API refreshes the underlying token before it expires while you call it with your API key, so a long-running worker keeps syncing without any refresh code. A grant stays valid until the user or the provider revokes it.

You still rotate your own credentials. Rotate the Nylas API key on a schedule by creating a new key, deploying it to your secrets manager, and revoking the old one after a short overlap so in-flight requests never fail. If a grant’s provider token is revoked upstream, the grant_status flips and API calls return an authentication error, which is your signal to obtain a fresh token and call POST /v3/connect/custom again for that account. Build a job that checks grant status on a cadence, since a 1 hour polling interval catches most expirations well before users notice. For the token mechanics and how to read expiry, see Get and refresh OAuth tokens.