Authentication
The connection URL is clean and the same for everyone:OAuth connector (recommended)
OAuth connector (recommended)
Brew is its own OAuth 2.1 authorization server, so most clients connect with no key to copy. Add the URL as a ChatGPT plugin or MCP connection; on first connect the client opens your browser to sign in with Brew and choose one brand. Organization admins can instead choose All brands. You can see and revoke the connection under Settings → API (“Connected via OAuth”). This is the first-party flow for ChatGPT, Claude, Grok, Cursor, Codex, VS Code, and the rest. See Connect your client.
API key (alternative)
API key (alternative)
For clients with no OAuth UI, or headless or CI setups, send a Brew API key as a bearer token instead:Create keys at Settings → API. A request with no or invalid credential returns
401; OAuth-capable clients use its challenge to begin discovery.OAuth Discovery and Security
Compatible clients discover authentication from Brew’s401 WWW-Authenticate challenge and protected-resource metadata. Brew publishes RFC 8414 authorization-server metadata (plus the OIDC discovery fallback), supports Dynamic Client Registration for public clients, and requires Authorization Code + PKCE S256. Redirect URIs are exact-match registered, web callbacks require HTTPS, and loopback HTTP remains available for desktop clients.
The only public OAuth scope is brew:all. Authorization and refresh
requests are bound to the exact resource audience
https://brew.new/api/mcp; unknown scopes and audience mismatches are
rejected. Access tokens last one hour and refresh tokens rotate.
Brew revalidates organization membership when exchanging an
authorization code and on every refresh. A brand grant requires active
organization membership. An organization grant also requires the
org:admin role. Confirmed removal or demotion returns
invalid_grant and revokes the grant. A membership-provider outage
returns retryable temporarily_unavailable without rotating or
revoking the token.
Brand Scoping
A connection is scoped either to one brand or to your whole organization, and there is never a brand in the URL. Brand-scoped: With OAuth, you pick the brand when you sign in. With an API key, the key carries it. Every call acts on that brand. Normally omitbrand_id; if supplied as an assertion, it must match the bound
brand or the call returns BRAND_SCOPE_MISMATCH.
Organization-scoped: Organization admins can choose “All brands”
at sign-in or create an organization-scoped API key. Every
brand-scoped tool then takes a required brand_id, while
organization-level tools take no selector.
There is no default brand on an organization connection: a call that omits brand_id is rejected rather than guessed. If the user has not made the brand unambiguous, ask before acting. get_brew_capabilities reports which scope the current connection has.
Because an organization connection can send from any brand,
send_email always requires an explicit confirmation step there. The
confirmation names the brand the mail will go out from.
Brand Lifecycle Workflow
- Call
list_brandsto discover available ids. - If the brand does not exist, call
create_brandwith anidempotency_key. - Poll
get_brand_statusuntilreadyistrueor the status isfailed. - Pass the response’s
brandIdvalue asbrand_idto brand-scoped tools.
list_brands and get_brand_status are authenticated discovery reads.
create_brand requires an organization-scoped credential with the
brands permission.
Safe Retries (Idempotency)
Every write tool accepts an optionalidempotency_key (≤ 100 chars). A repeat call with the same key replays the original result instead of acting twice; the same key with a different payload returns 409 IDEMPOTENCY_CONFLICT. This reuses the API’s Redis reserve/replay, so a key is honored identically across the MCP and HTTP surfaces. Always pass one on send_email. It is fail-closed (refuses with a retryable 503 if dedupe can’t be guaranteed) so a retry never sends a campaign twice.
Errors & Observability
Errors surface with an actionablecode, message, suggestion, and a request_id you can quote to support. Out-of-credits → INSUFFICIENT_CREDITS. Permission gaps and validation failures each return a distinct code.
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.