@postbrix/sdk
v1.0.0
Published
Official PostBrix SDK for Node.js, Bun, Deno, Cloudflare Workers, and Vercel Edge Runtime
Maintainers
Readme
PostBrix SDK
The Official TypeScript SDK for PostBrix — the API-first drag-and-drop email template builder platform for modern SaaS applications.
Render email templates programmatically with zero runtime dependencies. Designed for speed, security, and developer experience.
[!CAUTION] SECURITY NOTICE: Never expose
pb_live_secret API keys in browser or client-side code. The PostBrix SDK is designed primarily for trusted server-side environments (Node.js backend servers, serverless functions, background workers). Exposing your API key on the client enables unauthorized usage.
🌟 Core Features
- Zero Runtime Dependencies: Uses native Fetch and Web standard APIs for minimal footprint and maximum security.
- Universal Runtime Support: Node.js 18+, Bun, Deno, Cloudflare Workers, and Vercel Edge Runtime.
- Strictly Typed: Discriminated union response types (
format: "html" | "mjml" | "both") with compile-time TypeScript narrowing. - Transient Failure Retries: Built-in exponential backoff with jitter and automated
Retry-Aftercompliance. - Timeout Management: Guaranteed cleanup of native
AbortControllertimers without resource leaks. - Detailed Error Classes: Specific, actionable error classes with
statusCode,code,requestId, andretryablemetadata.
📦 Installation
npm
npm install @postbrix/sdkyarn
yarn add @postbrix/sdkpnpm
pnpm add @postbrix/sdkBun
bun add @postbrix/sdk📦 Module Systems
The SDK provides first-class support for both ES Modules (ESM) and CommonJS (CJS):
// ESM import (Node.js 18+, modern bundlers, Edge runtimes)
import { PostBrix } from "@postbrix/sdk";
// CommonJS require
const { PostBrix } = require("@postbrix/sdk");🚀 Quick Start
Basic HTML Render
import { PostBrix } from "@postbrix/sdk";
const postbrix = new PostBrix({
apiKey: process.env.POSTBRIX_API_KEY!,
});
const result = await postbrix.render("welcome-template", {
firstName: "Alex",
company: "Acme Inc.",
});
// Default format is "html"
console.log(result.html);📧 Rendering Templates
1. HTML Only (Default)
// Type is automatically inferred as HtmlRenderResponse
const result = await postbrix.render("welcome-template", {
firstName: "Alex",
});
// Direct access — result.html is guaranteed to be string
console.log(result.html);2. MJML Only
// Type is automatically inferred as MjmlRenderResponse
const result = await postbrix.render(
"welcome-template",
{ firstName: "Alex" },
{ format: "mjml" }
);
// Direct access — result.mjml is guaranteed to be string
console.log(result.mjml);3. Both Formats
// Type is automatically inferred as BothFormatsRenderResponse
const result = await postbrix.render(
"welcome-template",
{ firstName: "Alex" },
{ format: "both" }
);
// Direct access to both outputs
console.log(result.html); // string
console.log(result.mjml); // string4. Strongly Typed Variables (Generics)
You can optionally pass a TypeScript interface to assist with variable typing at compile-time:
interface WelcomeVariables {
firstName: string;
orderTotal: number;
}
const result = await postbrix.render<WelcomeVariables>(
"order-confirmation",
{
firstName: "Alex",
orderTotal: 149.99,
}
);[!NOTE] Template variables must be JSON-serializable (
Record<string, unknown>). Unsupported types likeBigInt,Function,Symbol,Map,Set, or circular structures will cause aPostBrixValidationErrorbefore any network request is sent.
⚠️ Error Handling
All SDK errors inherit from PostBrixError and expose useful diagnostic metadata:
statusCode?: number- HTTP response status codecode: string- Error code (e.g.INVALID_API_KEY,TEMPLATE_NOT_FOUND,RATE_LIMIT_EXCEEDED)requestId?: string- Server request identifier (fromX-Request-IDheader or response body)retryable: boolean- Whether the error was retryabledetails?: unknown- Detailed error information provided by the server
import {
PostBrix,
PostBrixError,
PostBrixAuthError,
PostBrixValidationError,
PostBrixTemplateError,
PostBrixLimitError,
PostBrixTimeoutError,
PostBrixNetworkError,
PostBrixResponseError,
} from "@postbrix/sdk";
const postbrix = new PostBrix({ apiKey: process.env.POSTBRIX_API_KEY! });
try {
const result = await postbrix.render("welcome-template", { name: "Alex" });
console.log(result.html);
} catch (error) {
if (error instanceof PostBrixAuthError) {
// HTTP 401 (Invalid/expired API key) or HTTP 403 (Forbidden)
console.error(`Auth failure [${error.code}]:`, error.message);
} else if (error instanceof PostBrixValidationError) {
// HTTP 400 or invalid template variables
console.error(`Validation error [${error.code}]:`, error.message, error.details);
} else if (error instanceof PostBrixTemplateError) {
// HTTP 404: Template not found
console.error(`Template not found:`, error.message);
} else if (error instanceof PostBrixLimitError) {
// HTTP 429: Rate limit exceeded
console.error(`Rate limited. Retry after: ${error.retryAfter}ms`);
} else if (error instanceof PostBrixTimeoutError) {
// Request exceeded timeout
console.error(`Request timed out:`, error.message);
} else if (error instanceof PostBrixNetworkError) {
// Network connectivity, DNS, or socket failure
console.error(`Network error:`, error.message);
} else if (error instanceof PostBrixResponseError) {
// Malformed response payload from API
console.error(`Response error:`, error.message);
} else if (error instanceof PostBrixError) {
// Base catch-all for any other PostBrix error
console.error(`PostBrix error [${error.code}]:`, error.message);
} else {
console.error("Unknown error:", error);
}
}⚙️ Configuration
interface PostBrixConfig {
/** API key for authentication (required, e.g. pb_live_xxxxxxxxx) */
apiKey: string;
/** Base URL for API endpoint (default: https://api.postbrix.com/v1) */
baseURL?: string;
/** Request timeout in milliseconds (default: 30000) */
timeout?: number;
/**
* Maximum number of retry attempts for transient failures (default: 2)
* 1 initial request + 2 retries = maximum 3 attempts
*/
maxRetries?: number;
}Example:
const postbrix = new PostBrix({
apiKey: process.env.POSTBRIX_API_KEY!,
baseURL: "https://api.postbrix.com/v1", // Trailing slashes are normalized automatically
timeout: 15000, // 15 seconds
maxRetries: 2, // 1 initial + 2 retries = 3 attempts max
});
// Inspect active configuration (API key is securely masked)
const config = postbrix.getConfig();
console.log(config);
// { baseURL: 'https://api.postbrix.com/v1', timeout: 15000, maxRetries: 2, apiKey: 'pb_live...[REDACTED]' }🔄 Retries & Rate Limiting
The SDK automatically retries transient errors:
- Retryable HTTP statuses:
429(Rate Limit),502(Bad Gateway),503(Service Unavailable),504(Gateway Timeout) - Retryable exceptions: Network failures (DNS, connection reset, socket error) and request timeouts
- Non-retryable statuses:
400(Validation),401(Unauthorized),403(Forbidden),404(Not Found),422(Unprocessable Entity)
Backoff Strategy & Jitter
- Uses exponential backoff: base delay of
500ms, doubling on each retry (500ms,1000ms,2000ms...), capped at10,000ms. - Random jitter (
0-100ms) is added to each interval to prevent synchronized retry spikes. - If the server responds with a
429 Too Many Requestsand aRetry-Afterheader, the SDK respects the server's requested delay instead of exponential backoff.
🌐 Runtime Compatibility
The SDK requires zero runtime dependencies and relies solely on Web Standard APIs (fetch, AbortController, Headers, Response).
Supported and tested runtimes:
- Node.js: >= 18.0.0 (CJS and ESM)
- Bun: >= 1.0.0 (CJS and ESM)
- Deno: >= 1.30.0 (ESM)
- Cloudflare Workers: Full compatibility
- Vercel Edge Runtime: Full compatibility
📚 Public TypeScript Exports
// Client
export { PostBrix } from "@postbrix/sdk";
// Types
export type {
PostBrixConfig,
RenderOptions,
RenderFormat,
RenderResponse,
RenderRequest,
HtmlRenderResponse,
MjmlRenderResponse,
BothFormatsRenderResponse,
ApiErrorResponse,
} from "@postbrix/sdk";
// Error Classes
export {
PostBrixError,
PostBrixAuthError,
PostBrixValidationError,
PostBrixTemplateError,
PostBrixLimitError,
PostBrixTimeoutError,
PostBrixNetworkError,
PostBrixResponseError,
} from "@postbrix/sdk";
// Constants
export { SDK_VERSION } from "@postbrix/sdk";📄 License
Proprietary Commercial License - All rights reserved.
This SDK is proprietary software. Usage is restricted to authorized customers with an active PostBrix subscription. See the LICENSE file for complete terms.
Copyright © 2026 PostBrix. All rights reserved.
