Summary and recommendation
Brevo exposes a REST user-management API under https://api.brevo.com/v3/organization/user/*, authenticated via a static API key passed as the api-key request header.
The key is shown only once at creation and has no programmatic rotation endpoint - store it in a secrets manager immediately.
Organization user endpoints are entirely separate from contact management endpoints (/contacts/*);
conflating the two is the most common integration error.
The API supports invite, update, delete, resend, and cancel-invitation operations, plus paginated list retrieval (default page size 10, max 50, offset-based).
Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are present on responses;
the API returns HTTP 429 on breach, but per-plan quotas for user-management endpoints are not published in a single reference table.
Enterprise limits are negotiated per contract.
Brevo has no native SCIM 2.0 endpoint.
Any identity graph or IdP expecting a /scim/v2/Users target will find no native support - all automated lifecycle management must be built on top of these REST endpoints.
SAML SSO is available (Enterprise included;
Business add-on), but SSO alone does not provision or deprovision user records.
API quick reference
| Has user API | Yes |
| Auth method | API Key (header: api-key) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise |
Authentication
Auth method: API Key (header: api-key)
Setup steps
- Log in to the Brevo dashboard at app.brevo.com.
- Navigate to your profile icon → SMTP & API → API Keys tab.
- Click 'Generate a new API key', assign a name, and optionally restrict permissions.
- Copy the generated key; it is shown only once.
- Include the key in all API requests as the header:
api-key: <YOUR_API_KEY>.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| user-management:read | Read access to organization users and their details. | GET /organization/user/list |
| user-management:write | Create, update, and delete organization users. | POST /organization/user/invitation/send, PUT /organization/user/update/{email}, DELETE /organization/user/{userId} |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| string | Email address of the organization user. | required | immutable (used as identifier) | Used as the unique identifier for user operations. | |
| userId | integer | System-assigned unique ID for the user. | auto-assigned | read-only | Returned in list/get responses; used in DELETE endpoint. |
| firstName | string | First name of the user. | optional | optional | |
| lastName | string | Last name of the user. | optional | optional | |
| role | string (enum) | Role assigned to the user within the organization. | required | optional | Accepted values include: owner, admin, manager, viewer. Exact enum values may vary; consult current API reference. |
| feature_access | object | Granular feature-level permissions granted to the user. | optional | optional | Contains boolean flags per Brevo product area (e.g., email campaigns, SMS, automation). |
| status | string (enum) | Invitation/activation status of the user. | auto-set to 'pending' | read-only | Values: active, pending. |
| hasPasswordSet | boolean | Indicates whether the user has set a password. | auto-assigned | read-only |
Core endpoints
List organization users
- Method: GET
- URL:
https://api.brevo.com/v3/organization/user/list - Watch out for: Returns only users within the authenticated account's organization; does not return contacts.
Request example
GET /v3/organization/user/list?limit=10&offset=0
api-key: <YOUR_API_KEY>
Response example
{
"users": [
{
"email": "alice@example.com",
"userId": 42,
"role": "admin",
"status": "active"
}
]
}
Invite a new user
- Method: POST
- URL:
https://api.brevo.com/v3/organization/user/invitation/send - Watch out for: An invitation email is sent immediately upon API call. Duplicate invitations to an already-active user return an error.
Request example
POST /v3/organization/user/invitation/send
api-key: <YOUR_API_KEY>
Content-Type: application/json
{
"email": "bob@example.com",
"role": "manager"
}
Response example
{
"message": "Invitation sent successfully."
}
Update user role/permissions
- Method: PUT
- URL:
https://api.brevo.com/v3/organization/user/update/{email} - Watch out for: The email in the path must be URL-encoded. You cannot change the user's email address via this endpoint.
Request example
PUT /v3/organization/user/update/bob%40example.com
api-key: <YOUR_API_KEY>
Content-Type: application/json
{
"role": "viewer"
}
Response example
{
"message": "User updated successfully."
}
Revoke/delete a user
- Method: DELETE
- URL:
https://api.brevo.com/v3/organization/user/{userId} - Watch out for: Deletion is immediate and irreversible. The account owner cannot be deleted via API.
Request example
DELETE /v3/organization/user/42
api-key: <YOUR_API_KEY>
Response example
HTTP 204 No Content
Resend user invitation
- Method: POST
- URL:
https://api.brevo.com/v3/organization/user/invitation/resend/{email} - Watch out for: Only works for users in
pendingstatus. Returns an error if the user is already active.
Request example
POST /v3/organization/user/invitation/resend/bob%40example.com
api-key: <YOUR_API_KEY>
Response example
{
"message": "Invitation resent successfully."
}
Cancel a pending invitation
- Method: DELETE
- URL:
https://api.brevo.com/v3/organization/user/invitation/cancel/{email} - Watch out for: Only applicable to users with
pendingstatus. Has no effect on active users.
Request example
DELETE /v3/organization/user/invitation/cancel/bob%40example.com
api-key: <YOUR_API_KEY>
Response example
HTTP 204 No Content
Get account details (authenticated user)
- Method: GET
- URL:
https://api.brevo.com/v3/account - Watch out for: Returns details of the account owner associated with the API key, not a specific sub-user.
Request example
GET /v3/account
api-key: <YOUR_API_KEY>
Response example
{
"email": "owner@example.com",
"firstName": "Jane",
"lastName": "Doe",
"companyName": "Acme Corp",
"plan": [{"type": "business"}]
}
Rate limits, pagination, and events
- Rate limits: Brevo enforces per-API-key rate limits that vary by plan. The official docs state limits per endpoint category but do not publish a single universal number.
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: The API returns HTTP 429 when rate limits are exceeded. The official docs note that
X-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Resetheaders are present on responses. Retry-After header behavior is not explicitly documented. - Pagination method: offset
- Default page size: 10
- Max page size: 50
- Pagination pointer: limit / offset
| Plan | Limit | Concurrent |
|---|---|---|
| Free | 400 requests/day (transactional email endpoints); general API limits apply | 0 |
| Starter / Business | Higher limits; exact per-endpoint quotas documented in the API reference per operation | 0 |
| Enterprise | Custom limits negotiated per contract | 0 |
- Webhooks available: Yes
- Webhook notes: Brevo supports webhooks for transactional and marketing email events (delivery, open, click, bounce, etc.) and for inbound email parsing. There are no documented webhooks specifically for organization user management events (e.g., user invited, user deleted).
- Alternative event strategy: Poll GET /organization/user/list on a schedule to detect user changes, as no user-lifecycle webhooks are documented.
- Webhook events: delivered, opened, clicked, hardBounce, softBounce, blocked, spam, unsubscribed, listAddition, contactUpdated, inboundEmailProcessed
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise
- Endpoint: Not documented
Limitations:
- Brevo does not document a native SCIM 2.0 endpoint.
- SAML SSO is available on Enterprise (included) or as a Business plan add-on (~$324/mo), but SCIM provisioning is not offered natively.
- IdP-driven provisioning (Okta, Entra ID) is not supported via SCIM; user lifecycle must be managed via the REST API or manually.
Common scenarios
Onboarding: POST /v3/organization/user/invitation/send with email, role, and optionally a feature_access object.
There is no webhook for invitation acceptance;
poll GET /v3/organization/user/list filtered by email to confirm status transitions from pending to active.
Use POST /v3/organization/user/invitation/resend/{email} if the invitation lapses - this endpoint only works while status is pending.
Deprovisioning: GET /v3/organization/user/list to retrieve the integer userId, then DELETE /v3/organization/user/{userId}.
Deletion is immediate and irreversible.
The account owner cannot be deleted via API;
ownership must be transferred in the dashboard before the API call will succeed.
Confirm removal with a follow-up GET.
Bulk role audit: Paginate GET /v3/organization/user/list with limit=50&offset=0, incrementing offset until the response set is smaller than the page size.
For each user with an over-privileged role, issue PUT /v3/organization/user/update/{email} - URL-encode the email in the path parameter (@ → %40).
You cannot update a user's email address via this endpoint.
Onboard a new team member
- POST /v3/organization/user/invitation/send with
emailandrole(and optionallyfeature_access). - User receives an invitation email and activates their account.
- Poll GET /v3/organization/user/list and filter by email to confirm
statustransitions frompendingtoactive. - If the invitation expires or is not received, POST /v3/organization/user/invitation/resend/{email}.
Watch out for: There is no webhook for invitation acceptance; polling is required to confirm activation.
Deprovision a departing employee
- GET /v3/organization/user/list to retrieve the
userIdfor the target user. - DELETE /v3/organization/user/{userId} to immediately revoke access.
- Verify removal by calling GET /v3/organization/user/list again and confirming the user is absent.
Watch out for: Deletion is permanent and immediate. The account owner cannot be deleted via API; ownership must be transferred in the dashboard first.
Bulk role audit and downgrade
- GET /v3/organization/user/list with pagination (
limit=50&offset=0) to retrieve all users. - Iterate pages until all users are collected.
- For each user whose
roleexceeds the desired level, call PUT /v3/organization/user/update/{email} with the correctedrolevalue. - Log responses to confirm successful updates.
Watch out for: Max page size is 50; accounts with more than 50 users require multiple paginated requests. URL-encode email addresses in path parameters.
Why building this yourself is a trap
The most consequential architectural caveat is the absence of SCIM: any identity graph or IdP that expects a /scim/v2/Users endpoint will find no native target in Brevo. Automated provisioning requires a custom middleware layer that translates IdP lifecycle events into Brevo REST calls, including handling invitation-based activation flows that have no direct SCIM equivalent.
The feature_access object for Restricted User permissions is not fully enumerated in the public API reference - available flags must be discovered empirically against a sandbox account before building provisioning logic. Additionally, API keys are account-scoped rather than user-scoped, meaning a compromised key exposes all organization user operations. There is no programmatic key rotation;
revocation and reissuance must be done manually in the dashboard, which creates a gap in automated secret-rotation workflows.
Automate Brevo workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.