Authorization: Bearer header or the convenience X-API-Key header.
Quickstart
Headers (Use ONE)
Send exactly one. Sending both is allowed; sending neither returns
401 AUTHENTICATION_REQUIRED. Malformed keys return 401 INVALID_API_KEY; revoked keys return 401 API_KEY_REVOKED.
Brand Binding (One Brand per Key)
Every API key is bound to exactly one brand at creation time. The binding is enforced server-side:- The brand id is resolved from the key on every request: clients never send a
brandIdfield. Sending one returns400 INVALID_REQUESTwithparam: "brandId". - All brand-scoped reads filter to the key’s brand automatically. Cross-brand identifiers surface as
404(not403) so the API never confirms the existence of resources in another brand. - All brand-scoped writes target only the key’s brand.
GET /v1/templates (the public template catalog). Every other endpoint is brand-scoped.
To operate on a different brand, switch brands in the dashboard at brew.new/settings/api and create a new key for that brand. A brand can have any number of keys (dev, staging, production, per-service, per-teammate); each acts on the same single brand it was created against.
Permission Scopes
Each key carries one or more permission scopes. Routes require either the route’s scope orall. Missing permission returns 403 INSUFFICIENT_PERMISSIONS with error.param pointing at the missing scope name.
Scope Implication (Coarse Scopes Satisfy Granular Ones)
Brew supports both coarse scopes (contacts, emails, automations) and granular least-privilege scopes (audiences, domains, sends). A coarse scope automatically satisfies the granular scopes it implies, so existing keys keep working. You only reach for the granular scopes when you want to lock a key down further.
The complete set of valid scope values accepted when a key is created is
contacts, emails, automations, audiences, domains, sends, transactional, and all.
Per-Route Required Scope
transactional is a reserved scope with no route today.
Principle of least privilege. For a back-end that only fires triggers, issue a key with automations only: even if it leaks, it can’t list contacts. For a service that only inspects send health, issue sends (it can read /v1/analytics/sends but not generate emails or manage domains). The dashboard surfaces each key’s scope set so you can audit + rotate.
Key Lifecycle
There is no API for key CRUD today: provisioning is human-in-the-loop through the dashboard so a compromised key can’t mint more. If you need programmatic key management for a SOC2 / SAST pipeline, contact us.
Production Security Checklist
What We Do NOT Support Today
For transparency:- OAuth 2.0 / token exchange for end-user authorization. The Brew Public API is server-to-server today; if you want per-user OAuth on top of the API, build it in your app and hold the Brew key on your server. Contact us if you have a use case that genuinely needs OAuth.
- PATCH idempotency. The
Idempotency-Keyheader is honored only onPOST.PATCHoperations are naturally idempotent at the resource level, so re-sending the same body is safe. - Public key-management API. Keys are minted from the dashboard.
Errors
See Errors for the full error envelope + every code in the catalog.
See Also
- API introduction: the overview that links every reference page.
- Idempotency: set
Idempotency-Keyon every retriedPOST. - Rate limits: per-route policies + the
429cookbook. - SDK authentication: TypeScript SDK auth specifics.
Need help?
Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:- Self-Service Tools
- Talk to Our Team
Search Documentation
Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.
ChatGPT/Claude Integration
Click “Open in ChatGPT” at the top right of any page to analyze documentation with ChatGPT or Claude for deeper insights.