JavaScript / TypeScript SDK
@boundry/sdk is a typed, zero-runtime-dependency fetch client for Boundry’s regional API.
Install
npm i @boundry/sdkQuickstart
Set BOUNDRY_API_KEY, then send from a domain verified in this project. The display-name form is valid; an unverified sending domain returns 422.
import { Boundry } from "@boundry/sdk";
const boundry = new Boundry({
apiKey: process.env.BOUNDRY_API_KEY,
region: "au",
});
const { id } = await boundry.emails.send({
from: "Acme <hello@acme.com>",
to: ["ava@northwind.com.au"],
subject: "Welcome to Acme",
html: "<p>It works.</p>",
});Client options
| Option | Type | Purpose |
|---|---|---|
apiKey | string | Project API key. Defaults to BOUNDRY_API_KEY when available. |
region | "au" | string | Regional endpoint selector, matching the region slug shown in the picker above. |
baseUrl | string | Full API base URL. Takes precedence over region when explicitly supplied. |
timeout | number | Per-request deadline in milliseconds. Defaults to 30,000. |
maxRetries | number | Retries after the first attempt. Defaults to 2. |
fetch | FetchFunction | Fetch implementation for tests or non-standard runtimes. |
Resources and methods
These rows are derived from the public OpenAPI operations and link to the generated endpoint reference. options? accepts request controls such as signal and idempotencyKey.
| SDK method | What it does | API reference |
|---|---|---|
boundry.apiKeys.list(options?) | List API keys | View endpoint → |
boundry.apiKeys.create(params, options?) | Create an API key | View endpoint → |
boundry.apiKeys.delete(keyId, options?) | Delete an API key | View endpoint → |
boundry.domains.list(options?) | List domains | View endpoint → |
boundry.domains.create(params, options?) | Create a domain | View endpoint → |
boundry.domains.delete(domainId, options?) | Delete a domain | View endpoint → |
boundry.domains.get(domainId, options?) | Get a domain | View endpoint → |
boundry.domains.update(domainId, params, options?) | Update domain tracking | View endpoint → |
boundry.domains.verifyAction(domainId, options?) | Verify a domain (compatibility action) | View endpoint → |
boundry.domains.verify(domainId, options?) | Verify a domain | View endpoint → |
boundry.emails.list(options?) | List sent emails | View endpoint → |
boundry.emails.send(params, options?) | Send an email | View endpoint → |
boundry.emails.get(emailId, options?) | Get a sent email | View endpoint → |
boundry.emails.listAttachments(emailId, options?) | List email attachments | View endpoint → |
boundry.emails.getAttachment(emailId, attachmentId, options?) | Download an email attachment | View endpoint → |
boundry.emails.batchSend(params, options?) | Send a batch of emails | View endpoint → |
boundry.events.list(options?) | List project events | View endpoint → |
boundry.events.get(eventId, options?) | Get a project event | View endpoint → |
boundry.inbound.listReceived(params?, options?) | List received emails | View endpoint → |
boundry.inbound.getReceived(emailId, options?) | Get a received email | View endpoint → |
boundry.inbound.ingest(params, options?) | Ingest an inbound email | View endpoint → |
boundry.logs.list(options?) | List event logs | View endpoint → |
boundry.openapi.get(options?) | Get the OpenAPI document | View endpoint → |
boundry.webhooks.list(options?) | List webhooks | View endpoint → |
boundry.webhooks.create(params, options?) | Create a webhook | View endpoint → |
boundry.webhooks.delete(webhookId, options?) | Delete a webhook | View endpoint → |
boundry.webhooks.get(webhookId, options?) | Get a webhook | View endpoint → |
boundry.webhooks.update(webhookId, params, options?) | Update a webhook | View endpoint → |
boundry.webhooks.listDeliveries(webhookId, params?, options?) | List webhook deliveries | View endpoint → |
boundry.webhooks.getDelivery(webhookId, deliveryId, options?) | Get webhook delivery detail | View endpoint → |
boundry.webhooks.retryDelivery(webhookId, deliveryId, options?) | Retry a webhook delivery | View endpoint → |
boundry.webhooks.rotateSecret(webhookId, params, options?) | Rotate a webhook signing secret | View endpoint → |
boundry.webhooks.test(webhookId, params, options?) | Send a synthetic webhook event | View endpoint → |
boundry.webhooks.verify(webhookId, options?) | Send a webhook ownership challenge | View endpoint → |
Errors
Non-success responses throw BoundryError, with status, code, and requestId. Connection failures throw BoundryConnectionError; request deadlines throw BoundryTimeoutError.
import { Boundry, BoundryError } from "@boundry/sdk";
const boundry = new Boundry({ apiKey: process.env.BOUNDRY_API_KEY });
try {
await boundry.emails.send({
from: "Acme <hello@acme.com>",
to: ["ava@northwind.com.au"],
subject: "Welcome to Acme",
html: "<p>It works.</p>",
});
} catch (error) {
if (error instanceof BoundryError) {
console.error(error.status, error.code, error.requestId);
}
}Retries and idempotency
The SDK retries connection failures and 408, 429, and 5xx responses with exponential full jitter, up to maxRetries (2 by default), and honours Retry-After. It automatically creates an idempotency key for emails.send; pass { idempotencyKey: "..." } as the second argument when you need a stable key, including for another non-idempotent request.
Regions and runtimes
region: "au" resolves to https://api.au.boundry.dev. Set baseUrl explicitly only when you need to override region.
import { Boundry } from "@boundry/sdk";
const boundry = new Boundry({
apiKey: process.env.BOUNDRY_API_KEY,
baseUrl: "https://api.au.boundry.dev",
});It supports Node 18+, Cloudflare Workers, Deno, Bun, and modern browsers with a Fetch implementation. Keep project API keys on a trusted server rather than exposing them in browser-delivered code.