> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.brevo.com/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 <access_token>
    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.