Skip to main content

Main Error Type

The TypeScript SDK throws one typed error class for API failures:
BrewApiError gives you:
  • status
  • code
  • type
  • message
  • param
  • suggestion
  • docs
  • requestId
  • retryAfter
  • idempotencyKey — the Idempotency-Key the request carried; replay a write with it
  • bodyError — set when the error body was cut off mid-read (the message says so)

Typical Catch Pattern

What to Branch On

  • Use type for broad categories like not_found or rate_limit.
  • Use code for specific product cases like CONTACT_NOT_FOUND.

Current Error Codes

Use the full error code catalog for current codes, statuses, and recovery guidance. The SDK exposes every envelope field through BrewApiError, so your branches remain typed as the catalog evolves.

API Errors vs Transport Errors

There are two buckets:

API Error

The server answered with a non-2xx response. You get BrewApiError.

Transport Error

No usable answer arrived, and retries were exhausted. You get a BrewTransportError — a normal Error subclass, never a BrewApiError, since there is no status or envelope to report:
  • BrewTimeoutError — the deadline passed while waiting for the response headers or while reading the body. Its name is 'TimeoutError'.
  • BrewConnectionError — the connection failed, or dropped while the body was streaming. The original error is on cause.
A 2xx whose body is not JSON throws BrewParseError (report its requestId). If you cancel, the request rejects with your signal’s reason.
Or branch on what happened:

Timeouts and Cancellation

  • timeoutMs (default 30_000, per attempt) covers the whole attempt: connecting, waiting for the headers, and reading the response body. A server that answers and then stalls fails at the deadline instead of hanging.
  • Timeouts are retried like other transient failures. Pass retryOnTimeout: false (on the client or per request) for a hard deadline: one attempt, then BrewTimeoutError.
  • Cancel with an AbortSignal — per request ({ signal }) or for every request on the client (createBrewClient({ signal })). It stops the request wherever it is, including a retry backoff, is never retried, and rejects with the signal’s reason.
  • Long-running methods set their own per-call timeout (emails.generate 240 s, content.gif 300 s, …). It only ever raises a shorter client timeoutMs; a per-request timeoutMs always wins.

Replay, don’t resend

A timeout, a dropped connection or a cancel tells you nothing about whether the server did the work — cancelling does not stop work the server has started. To finish a write without doing it twice, replay it later with the same idempotency key. Every SDK error carries the key its request used as error.idempotencyKey, including one the SDK generated for a POST. A cancel rejects with your own reason, so on a write you might cancel, pass your own idempotencyKey and keep it. If a retry finds the first attempt still running, the SDK throws the original timeout or connection error with inProgress: true rather than a conflict: wait, then replay with the same key (the API holds an in-flight key for up to 15 minutes, and replays a finished one for 24 hours). The replay guarantee needs the API’s idempotency store. While it is degraded, real sends refuse with a retryable 503 rather than risk sending twice, and other writes run without the guarantee. So for a write that must not happen twice (creating a brand, say), pass maxRetries: 0 on that call — otherwise the SDK’s own retry after a timeout or dropped connection can re-run it before you can look — and check whether the first attempt landed before you retry it yourself.

Helpful Notes

  • Log requestId when asking Brew support for help.
  • Trust the SDK retry behavior first before adding your own retry loop.
  • For POST requests, let the SDK keep idempotency on by default, and replay an unknown outcome with error.idempotencyKey rather than resending with a new key.

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:

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 explore it further with ChatGPT or Claude.