> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://developers.brevo.com/docs/oauth/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.brevo.com/_mcp/server. # OAuth 2.0 Brevo's OAuth 2.0 support covers two different flows, depending on **who's authenticating**: #### [Machine-to-machine (M2M)](/docs/oauth-m2m-authentication) Your server calls Brevo as itself — no user, no consent screen.\ \ **When to use?**\ Any backend integration that would otherwise use a static API key. Recommended default for new server-to-server work. #### [OAuth apps](/docs/apps-getting-started) Your app acts on behalf of a Brevo user, who authorizes it via a consent screen.\ \ **When to use?**\ Apps that need a specific user's data or permissions, not your own account's. ## Which flavor of OAuth do I need? If your integration is a backend service calling Brevo on its own behalf — the same role a static API key plays today — use **[machine-to-machine](/docs/oauth-m2m-authentication)**. It's scoped and short-lived where an API key is all-access and long-lived, and it's the recommended replacement for a static API key in new integrations. Reach for the **authorization_code** flow below only when there's an actual Brevo *user* in the loop: your app needs to act with that specific user's permissions, and they need to see and approve a consent screen. ## API key vs OAuth 2.0 | | API key | Machine-to-machine | OAuth apps (user consent) | | --------------------- | -------------------------- | ----------------------------------------- | --------------------------------------------- | | **Who authenticates** | Your server | Your server, as itself | The end user | | **Best for** | Simple direct integrations | Server-to-server (recommended default) | Apps acting on behalf of users | | **Setup** | Copy key from dashboard | `brevo app create --m2m` | `brevo app create` | | **Token lifetime** | Until revoked | Access token: \~1 hour · No refresh token | Access token: 1 hour · Refresh token: 30 days | The rest of this page covers the **OAuth apps** (`authorization_code`) flow — for machine-to-machine, see [Machine-to-machine (M2M)](/docs/oauth-m2m-authentication) instead. ## How it works ```mermaid sequenceDiagram participant Dev as Developer (one-time setup) participant User as End User participant App as Your App participant Auth as oauth.brevo.com participant API as api.brevo.com Note over Dev: One-time setup via CLI Dev->>App: brevo app create → client_id + client_secret Note over User,API: Per-user authorization flow User->>App: Visits your app App->>Auth: Redirect to /authorize?client_id=…&redirect_uri=…&scope=contacts:read contacts:write&state=xyz Auth-->>User: Brevo login + consent for requested scopes User->>Auth: Signs in and authorizes Auth->>App: Redirects to redirect_uri?code=AUTH_CODE&state=xyz App->>Auth: POST /token (code + client_id + client_secret) Auth-->>App: access_token + refresh_token App->>API: Request with Authorization: Bearer API-->>App: Response data ``` ## Key concepts | Term | Description | | --------------- | --------------------------------------------------------------------------------------------------------------------- | | `client_id` | Unique identifier for your OAuth app — safe to expose client-side | | `client_secret` | Secret used to authenticate your app with Brevo — **never expose this** | | `redirect_uri` | URL Brevo redirects to after the user authorizes — must be pre-registered | | `scope` | Permissions your app requests, e.g. `contacts:read` or `transactional.email:write`. See [Scopes](/docs/oauth-scopes). | | `access_token` | Bearer token included in API requests. Expires after **1 hour**. | | `refresh_token` | Used to obtain a new access token when the current one expires. Valid for **30 days**. | ## Scopes Scopes are the permissions your app requests on a user's Brevo account. Each scope follows the pattern `{resource}:{action}` — for example, `contacts:read` to list contacts or `transactional.email:write` to send transactional emails. * New apps created with `brevo app create` are seeded with `contacts:read`, `contacts:write`, `crm:read`, `crm:write`. Change them by editing `auth.scopes` in `app-config.json` and running `brevo app upload`. * `:write` does **not** imply `:read`. Request both if your app needs both. * Request the minimum your app needs — users see every requested scope on the consent screen. See the [Scopes reference](/docs/oauth-scopes) for the full catalog and how to inspect a token's scopes. > **Warning** > > **OAuth apps are currently private only.** A private app can only be authorized by users within your own Brevo organisation — it cannot be distributed to external users or listed in any marketplace. This makes it suitable for internal tools, automations, and integrations you build for your own team. > > Support for public apps — where any Brevo user can authorize your integration — is planned for a future release. ## Building an app? Creating an OAuth app, requesting scopes, and the full authorization-code walkthrough now live under **[Apps](/docs/apps)**. #### [Create your first app](/docs/apps-getting-started) Install the CLI and create your first Brevo app. > Token-based authentication — machine-to-machine or on behalf of a user ## Docs - [Machine-to-machine (M2M)](https://developers.brevo.com/docs/oauth-m2m-authentication.md): Scoped, short-lived credentials for server-to-server calls — no user, no static key