Skip to navigation

Private and public apps

Choose who can use your app, and how to get a public app reviewed and distributed.
View as Markdown

Every Brevo app has a distribution type: private or public. It decides who can authorize your app, and it’s set once, when you create the app.

  • A private app is for your own organization: internal tools, automations, and integrations you build for your own team. It works as soon as you create it.
  • A public app is for every Brevo user: for example, a SaaS product that offers a Brevo integration to its own customers. It goes through a review by Brevo, and once approved, any Brevo account can authorize it.

Public apps require Brevo CLI 2.5.0 or later. Run brevo --version to check, and see Upgrading to update.

Private vs public at a glance

Private appPublic app
Who can authorize itUsers in your own Brevo organizationAny Brevo account, once approved
Review by BrevoNone, usable right awayRequired before it’s available to other accounts
How users find itYou share it within your organizationYou distribute it: an install link in your product, or a listing on third-party marketplaces. Public apps aren’t listed on a Brevo marketplace.
App typesOAuth (consent-based or machine-to-machine), UI apps, Brevo FunctionsConsent-based OAuth apps only (UI apps can’t be public for now)
OAuth clientConfidential client with a client secretAuthorization code with PKCE, no client secret
Brevo Developer TermsNo agreement stepYou agree to them when you create the app, and confirm them again when you submit it
Change the distribution laterNot possibleNot possible

The distribution type is fixed at creation. brevo app upload refuses a changed distribution_type. To move an integration from private to public, create a new public app.

Which one should you choose?

  • Choose private if only your own organization will use the app, if your backend calls the API as itself (M2M), or if you’re building a Brevo Function or a UI app (UI apps can’t be public for now).
  • Choose public if users outside your organization will connect their own Brevo accounts to your product.

Create a public app

1

Create the app with public distribution

brevo app create --distribution public

Or run brevo app create and choose Public when asked “What distribution type should this app use?”. Non-interactive runs (--json or piped input) default to private, so pass --distribution public explicitly.

2

Agree to the Brevo Developer Terms

Right after you choose Public, the CLI opens the Brevo Developer Terms in your browser and asks:

? Do you confirm that you have read and agree to the Brevo Developer Terms? (y/N)

Answering no cancels the creation; nothing is sent to Brevo. In scripts and CI, where no question can be asked, add --accept-developer-terms to confirm agreement explicitly:

brevo app create --name "My App" --distribution public \
--redirect-uri https://myapp.com/callback \
--accept-developer-terms --json
3

Choose OAuth app and add your OAuth callback URLs

When asked “What type of app are you building?”, choose OAuth app. UI apps can’t be public for now. A public app is always a consent-based OAuth app, so the CLI doesn’t ask which OAuth flow to use. Add at least one OAuth callback URL (http:// or https://): the URL users are sent back to after they authorize your app. Use your production callback URL here, or add it later in auth.redirect_uris in app-config.json and run brevo app upload.

4

Build the OAuth flow with PKCE

A public app has no client secret. It uses the authorization code flow with PKCE (S256): your server creates a random code_verifier for each authorization, sends its SHA-256 hash as code_challenge on the authorize request, and presents the verifier on the token exchange instead of a client_secret.

The test server from brevo app scaffold already does this for a public app. See Distribute your app with an install link below for the exact requests.

Submit your app for review

Before you submit, your app needs to be complete on Brevo’s side:

  • Upload it at least once. Run brevo app upload so Brevo has a version to review.
  • Fill in the required fields. For example, set logo_uri in app-config.json to your logo URL, then run brevo app upload. If a field is missing, brevo app submit lists it by the name the Brevo API uses (for example logoLink), which can differ from the app-config.json key.
  • Keep app-config.json in sync. If your local file differs from the app on Brevo (name, redirect URLs, scopes, logo or version), brevo app submit stops and shows the difference. Run brevo app upload to push your local changes, then submit again.

Then run:

brevo app submit

The CLI shows the app configuration being submitted and asks you to confirm this statement:

I have read and agree to the Brevo Developer Terms. I confirm that the information in this submission is accurate and complete, and that my app complies with the Brevo Developer Terms and all applicable laws. I understand that Brevo’s activation of my app does not constitute a review, certification, or endorsement of my app.

Once you confirm, the CLI opens a submission form in your browser. Your app is submitted only when you complete and send that form.

In scripts, --json prints the form URL instead of opening a browser, and --accept-submission-terms confirms the statement:

brevo app submit --app-id <app-id> --json --accept-submission-terms
{ "app_id": "<app-id>", "form_url": "https://…" }

Track the review

Brevo emails you the decision, generally within 7 days. You can check where your app stands at any time:

brevo app status
StatusMeaning
draftSet up, but not submitted for review yet
submittedSubmitted and waiting to be reviewed
in_reviewBeing reviewed by Brevo
approvedApproved: any Brevo account can now authorize your app
rejectedNot approved. Check your email for the details.
changes_requestedChanges were requested. Check your email for the details.
unknownNo status is available yet. Check that the app is public and that you’ve run brevo app upload.

Reviewer feedback is sent by email only; brevo app status shows the status, not the feedback. Add --json to get { "state": "…", "message": "…" }.

Brevo doesn’t list public apps on a Brevo marketplace. Once your app is approved, you decide where users find it, for example inside your own product or on third-party marketplaces.

Your install link is a URL on your own server, for example https://yourapp.com/connect/brevo. The CLI doesn’t generate one for you. Because of PKCE, the Brevo authorize URL is different for every authorization, so your server builds it each time someone opens your install link. If you’re a SaaS product building an integration with Brevo, you can add the install link inside your product, for example as a Connect Brevo button. You can also use the same link in a third-party marketplace listing.

1

Redirect the user to Brevo

Get your app’s client_id from the brevo app create output or with brevo app credentials. A public app has no client secret.

When someone opens your install link, your server creates a state value and a code_verifier, keeps both server-side, and redirects the user to:

https://oauth.brevo.com/realms/partner/oauth/authorize
?response_type=code
&client_id=<CLIENT_ID>
&redirect_uri=<REDIRECT_URI>
&state=<STATE>
&scope=<SPACE_SEPARATED_SCOPES>
&code_challenge=<BASE64URL_SHA256_OF_CODE_VERIFIER>
&code_challenge_method=S256

The user signs in to their Brevo account and approves the scopes your app requests.

2

Exchange the code for tokens

Brevo redirects back to your redirect_uri with a code and the state. Check that state matches, then exchange the code. Send the code_verifier, not a client secret:

curl --request POST \
--url https://oauth.brevo.com/realms/partner/oauth/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=<CLIENT_ID>' \
--data-urlencode 'code_verifier=<CODE_VERIFIER>' \
--data-urlencode 'code=<CODE>' \
--data-urlencode 'redirect_uri=<REDIRECT_URI>'

Store the user’s tokens, then call the API with Authorization: Bearer <access_token>. To refresh, send grant_type=refresh_token, client_id and refresh_token to the same token endpoint, with no client_secret. The OAuth integration guide covers the token response and errors.

Update an approved app

Changing an approved app’s scopes requires a new review. Edit auth.scopes in app-config.json, run brevo app upload, then run brevo app submit and wait for Brevo’s email.

Withdraw an app

brevo app withdraw

Withdrawing takes your app out of submission. If your app was approved, the approved version is no longer available to Brevo accounts. To make it available again, run brevo app submit and go through the review again.

The command asks for confirmation; add --force to skip it in scripts. If the app was never submitted, it tells you so and changes nothing.