@brew.new/sdk
v6.0.0
Published
Official TypeScript SDK for the Brew public API.
Readme
@brew.new/sdk
Official TypeScript SDK for the Brew public API.
- Resource-oriented surface —
brew.contacts.upsert(...)instead of raw HTTP plumbing. - One typed error class (
BrewApiError) for every non-2xx path. - Safe retries with exponential backoff + jitter.
- Auto-generated
Idempotency-Keyon POST so retries never double-write. - Node 20+, server-first. API keys are secrets — do not use this SDK directly in a browser.
Install
bun add @brew.new/sdk
# or
npm install @brew.new/sdkQuick start
import { createBrewClient } from '@brew.new/sdk'
const brew = createBrewClient({
apiKey: process.env.BREW_API_KEY!,
})
const contact = await brew.contacts.upsert({
email: '[email protected]',
firstName: 'Jane',
customFields: { plan: 'enterprise' },
})
const found = await brew.contacts.getByEmail({ email: '[email protected]' })That's the whole shape. Every other method follows the same pattern.
Pointing at a different environment
baseUrl is configurable. By default it points at production
(https://brew.new/api), but you can override it for staging, local
development, or a custom proxy:
const brew = createBrewClient({
apiKey: process.env.BREW_API_KEY!,
baseUrl: process.env.BREW_API_URL ?? 'https://brew.new/api',
})Common values:
https://brew.new/api— production (default)https://staging.brew.new/api— staginghttp://localhost:3000/api— your own dev server
Trailing slashes are normalized either way. See
docs/configuration.md for the full list of
config options (timeoutMs, maxRetries, userAgent, custom fetch,
etc.).
Documentation
| Topic | File |
| --------------------------- | ---------------------------------------------------------------------- |
| Analytics resource | docs/analytics.md |
| Audiences resource | docs/audiences.md |
| Brand resource | docs/brand.md |
| Client configuration | docs/configuration.md |
| Contacts resource | docs/contacts.md |
| Domains resource | docs/domains.md |
| Emails resource | docs/emails.md |
| Fields resource | docs/fields.md |
| Integrations resource | docs/integrations.md |
| Error handling | docs/errors.md |
| Retries + idempotency | docs/retries-and-idempotency.md |
| Sends resource | docs/sends.md |
| Templates resource | docs/templates.md |
| Usage resource | docs/usage.md |
| Development + OpenAPI sync | docs/development.md |
| Releasing a new version | RELEASING.md |
Note: there is no brand management resource.
brew.brand.get()is read-only — it returns the single brand bound to your API key (selected when the key is created in the dashboard) plus its extraction readiness.
Development
Use a modern Node 20 or newer runtime for SDK development. On this
machine, Vitest worked with Node 20.19.2 and newer, but failed on the
older system Node 20.10.0.
bun install
bun tsc # typecheck
bun lint # eslint
bun run format # prettier
bun run test # vitest — NOT `bun test`, that hits Bun's built-in runner and bypasses MSW setup
bun run build # tsup: dist/ with esm + cjs + .d.tsFull contribution + testing conventions live in AGENTS.md.
The big one: every change is driven red → green via vitest + MSW, no
exceptions for "trivial" pure functions.
License
MIT
