- Usage-metered: email generation, email import, AI email edits, semantic brand-image search, and image generation charge the actual model usage (token input/output for the email agent; embedding/image-gateway cost for search + image generation). The cost scales with the work, so there is no fixed number and no
X-Credit-Costheader. The call still gates: an empty balance is rejected up front. - Fixed: every other media/render operation charges a flat, published per-operation cost, reported via the
X-Credit-Costresponse header.
Which operations cost credits
| Operation | Route | Metering |
|---|---|---|
| Generate an email | POST /v1/emails | Usage (tokens) |
| Import an email (HTML / MJML / JSX → editable design) | POST /v1/emails/import | Usage (tokens) |
| Edit an email (AI prompt edit) | PATCH /v1/emails/{emailId} | Usage (tokens) |
| Semantic brand-image search | GET /v1/brand/images?q=… | Usage (embedding) |
| Generate an image | POST /v1/content/generate-image | Usage (image) |
| Preview an email across real inboxes/devices | POST /v1/emails/{emailId}/client-previews | Fixed |
| Audit an email’s accessibility (WCAG 2.1) | POST /v1/emails/{emailId}/accessibility-audit | Fixed |
| Validate contact deliverability | POST /v1/contacts/validate | Fixed (per address) |
| Validate on ingestion (opt-in) | POST /v1/contacts / POST /v1/contacts/import-csv with validate: true | Fixed (per address) |
| Generate / animate a GIF | POST /v1/content/gif (from: "prompt" | "image" | "video") | Fixed |
| Optimize / resize an image | POST /v1/content/transform (operation: "optimize" | "resize") | Fixed |
| Render HTML to a PNG | POST /v1/content/html-to-png | Fixed |
| Add an image (saves to the brand image library) | POST /v1/content/add-image | Fixed |
q browse of GET /v1/brand/images).
Contact validation is metered per address, the
X-Credit-Cost for a call is the per-address cost times the number of addresses you submit (e.g. validating 100 addresses charges 100× the unit cost). See GET /v1/help → credits.operations for the current per-address unit. The same per-address rate applies to the opt-in validate: true flag on POST /v1/contacts and POST /v1/contacts/import-csv; batches over 100 addresses upsert first and validate as a background job that meters per address as it runs.X-Credit-Cost response header. For usage-metered operations the charge equals the real token/image cost the work incurred (no header). The full per-operation metering table is available machine-readably at GET /v1/help → credits.operations.
These fixed-cost calls are value-aligned. You are never charged for an empty result. The client-preview render bills only when at least one client actually produces a screenshot; the accessibility audit bills only when it completes; contact validation bills only when at least one address is checked. If nothing is produced (nothing finished in time, or the service is temporarily unavailable) the call returns a retryable
503 SERVICE_UNAVAILABLE and is not billed.Check your balance: GET /v1/usage
There is no dry-run cost preview. Credit-metered calls just charge on success; if you want to know what you can afford before you call, read your balance from the billing surface:
null limit / remaining means unlimited. credits is the AI/media balance; emailSends is your monthly delivery allowance. Both reset at the period.end boundary. GET /v1/usage requires the emails scope.
What a real (charged) call reports
A successful fixed-cost call charges the published cost exactly once and returns two headers:| Header | Meaning |
|---|---|
X-Credit-Cost | Credits charged for this call. |
X-Credits-Remaining | Balance after the charge. |
GET /v1/usage before and after to see the delta.
Charging is idempotent: a retry with the same Idempotency-Key replays the original response and is not charged again.
Errors
| Code | Status | When |
|---|---|---|
INSUFFICIENT_CREDITS | 402 | Your balance is too low: below the fixed cost (fixed ops) or empty (usage-metered ops). details carries { cost, remaining, planKey }. Top up / upgrade. There’s no Retry-After because credits reset at the billing-period boundary (read it from GET /v1/usage’s period.end). |
SERVICE_UNAVAILABLE | 503 | The credit balance could not be verified (a transient billing-backend outage). The gate fails closed. It refuses rather than do paid work it can’t meter. Retryable: a Retry-After header tells you when. |
402 is a confirmed empty balance; 503 is “can’t check right now, try again shortly”. Branch on the code, never on the message.
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.