Use the Sendrealm JavaScript SDK from trusted server-side or edge environments to call the Sendrealm API.
This SDK uses a Sendrealm API key. Do not use it to register browsers or mobile devices for push. Use the Android, iOS, React Native, or React Web Push SDK for device registration.
Do not expose a Sendrealm API key in browser JavaScript or mobile app code. API keys are server-side secrets.
Runtime Support
The SDK uses native fetch and has no runtime dependencies.
- Node.js 18 or newer.
- Cloudflare Workers.
- Deno.
- Bun.
- Vercel Edge Runtime.
- Other runtimes with
fetch, Headers, Request, and Response.
Install
npm install @sendrealm/sdk
Create An API Key
Create an API key in the Sendrealm dashboard and store it in your secret manager or environment variables.
See API Keys for dashboard setup.
Create A Client
import Sendrealm from "@sendrealm/sdk";
const client = new Sendrealm({
apiKey: process.env.SENDREALM_API_KEY,
projectId: process.env.SENDREALM_PROJECT_ID,
});
If SENDREALM_API_KEY is set, the client can read it automatically:
import Sendrealm from "@sendrealm/sdk";
const client = new Sendrealm();
Client Options
Use client options for custom timeouts, retries, headers, or fetch behavior:
const client = new Sendrealm({
apiKey: process.env.SENDREALM_API_KEY,
timeout: 60_000,
maxRetries: 2,
fetch: customFetch,
defaultHeaders: {
"X-App": "my-service",
},
});
Important options:
apiKey: required unless SENDREALM_API_KEY is set.
projectId: optional project selector; defaults to SENDREALM_PROJECT_ID, then to the API key’s default project.
timeout: request timeout in milliseconds.
maxRetries: number of automatic retries for retryable failures.
fetch: custom fetch implementation.
defaultHeaders: headers sent with every request.
defaultQuery: query parameters sent with every request.
apiKey may also be an async function if your service rotates credentials.
Send Email
const email = await client.emails.send({
from: "hello@example.com",
to: ["user@example.com"],
subject: "Welcome",
text: "Hello from Sendrealm",
html: "<p>Hello from Sendrealm</p>",
});
Before sending production email, make sure the sending domain is verified in Sendrealm.
Send Push
Send push notifications to registered devices:
await client.push.notifications.send({
app_id: "app_123",
emails: ["user@example.com"],
notification: {
title: "Your order shipped",
body: "Track it now",
launch_url: "https://example.com/orders/123",
},
});
Push sending requires device setup first:
- Android devices use the Android or React Native SDK.
- iOS devices use the iOS or React Native SDK.
- Web browsers use the React Web Push SDK.
- Firebase, APNs, or Web Push provider settings must be configured in Sendrealm.
Test And Diagnose Push
Use API-key resources from trusted backend code to inspect setup and prove one
device end to end:
const apps = await client.push.apps.list();
const app = apps[0];
const providers = await client.push.apps.listProviders(app.public_id);
const devices = await client.push.devices.list({
app_id: app.public_id,
environment: "development",
subscribed: true,
});
const test = await client.push.tests.create({
app_id: app.public_id,
device_id: devices.data[0].device_id,
title: "Sendrealm test",
body: "Push registration is working",
});
const trace = await client.push.tests.retrieve(test.id);
Raw APNs, FCM, and Web Push credentials are not returned by app or device
resources. Push campaign SDK methods create and edit drafts, preview reachable
devices, and test a draft on one device; they do not schedule or launch it.
Ingest Events
await client.events.ingest({
event: "order.completed",
email: "user@example.com",
payload: {
order_id: "order_123",
total: 42,
},
idempotency_key: "order_123_completed",
});
Each event should include one identity, such as contact_id, external_id, or email.
Use an idempotency_key when your system might retry the same event.
For correlated journeys such as checkout recovery, pass the business identifier
on every related event:
await client.events.ingest({
event: "checkout.started",
email: "user@example.com",
correlation: { key: "checkout_id", value: "checkout_123" },
contact: { mode: "upsert", fields: { first_name: "Olivia" } },
});
Avoid putting sensitive personal data in event data unless your team intentionally wants that data in Sendrealm.
List contacts with cursor pagination:
for await (const contact of client.contacts.list({ limit: 100 })) {
console.log(contact.email);
}
Create a contact:
const contact = await client.contacts.create({
email: "user@example.com",
fields: {
first_name: "Olivia",
plan: "pro",
},
});
Update a contact:
await client.contacts.update(contact.id, {
fields: {
plan: "enterprise",
},
});
Look up or upsert a contact by email:
const existing = await client.contacts.getByEmail("user@example.com");
const contact = await client.contacts.upsert({
email: "user@example.com",
fields: { plan: "enterprise" },
});
Use backend-owned contact fields for authoritative customer data such as billing plan, account status, compliance flags, and verified profile data.
Dashboard Resources
Use API-key-scoped resources to inspect the current project, choose a verified domain, and create campaign drafts:
const project = await client.project.retrieve();
const domains = await client.domains.list();
const verifiedDomain = domains.data.find(domain => domain.status === "verified");
if (!verifiedDomain) {
throw new Error("A verified sending domain is required.");
}
const campaign = await client.campaigns.create({
name: "July product update",
});
await client.campaigns.update(campaign.id, {
subject: "What changed in July",
from: {
name: "Sendrealm",
address: `hello@${verifiedDomain?.name}`,
},
audience_ids: ["018f4a28-29f0-7a2e-86c3-6a8f1b6dd294"],
content: {
type: "doc",
content: [],
},
});
Campaign APIs create and update drafts only. Review readiness and schedule or send the campaign from the SendRealm dashboard.
Automations
Validate drafts before publishing, inspect runs, and use no-send test runs for
waits and timeout paths:
const validation = await client.automations.validate(definition);
const testRun = await client.automations.tests.create(automationId, {
event: "checkout.started",
email: "user@example.com",
correlation: { key: "checkout_id", value: "checkout_123" },
});
await client.automations.tests.advance(testRun.id, 3600);
await client.automations.runs.cancel(runId, {
reason: "Customer completed checkout elsewhere",
});
Some list endpoints return cursor pages. Consume every item with for await:
for await (const contact of client.contacts.list({ limit: 100 })) {
console.log(contact.email);
}
Or inspect pages manually:
let page = await client.contacts.list({ limit: 20 });
while (page.hasNextPage()) {
page = await page.getNextPage();
}
Errors
Non-2xx responses throw typed errors:
import Sendrealm, { APIError, RateLimitError } from "@sendrealm/sdk";
try {
await client.contacts.retrieve("missing");
} catch (error) {
if (error instanceof RateLimitError) {
console.log(error.headers.get("retry-after"));
}
if (error instanceof APIError) {
console.log(error.status, error.code, error.message);
}
}
Common error categories:
- Authentication errors: check the API key.
- Permission errors: check key scope and project access.
- Validation errors: check required fields and request shape.
- Rate limits: retry after the server-provided delay when available.
- Connection errors: check network and runtime fetch behavior.
Edge Runtime Examples
Cloudflare Workers:
import Sendrealm from "@sendrealm/sdk";
export default {
async fetch(_request: Request, env: Env) {
const client = new Sendrealm({
apiKey: env.SENDREALM_API_KEY,
});
await client.events.ingest({
event: "worker.received",
external_id: "visitor_123",
});
return new Response("ok");
},
};
Deno:
import Sendrealm from "npm:@sendrealm/sdk";
const client = new Sendrealm({
apiKey: Deno.env.get("SENDREALM_API_KEY"),
});
Bun:
import Sendrealm from "@sendrealm/sdk";
const client = new Sendrealm({
apiKey: Bun.env.SENDREALM_API_KEY,
});
Production Checklist
- API key is stored in a secret manager or environment variable.
- API key is never sent to browser or mobile code.
- Sending domains are verified for email.
- Device SDKs are installed before backend push sends target app users.
- Event names are stable.
- Event submissions use
idempotency_key where retries are possible.
- Errors are logged with status, code, and message.
- Rate limit responses are handled.
Related Pages