The official Node.js SDK for Reloop, providing a convenient wrapper around the Reloop REST API.
Install the package via npm:
npm install reloop-emailInitialize the client with your API key. You can find or generate your API key in the Reloop Dashboard.
import { Reloop } from "reloop-email";
const reloop = new Reloop({
apiKey: "rl_your_api_key_here",
});reloop.apiKeyswas renamed toreloop.apiKeyto match the API docs.
The SDK supports full CRUD and lifecycle management for API keys.
const response = await reloop.apiKey.list({ page: 1, limit: 10 });
console.log(response.apiKeys);
console.log(response.total);const newKey = await reloop.apiKey.create({ name: "Production Key" });
console.log(newKey.key); // Secret key (only returned on create or rotate)const key = await reloop.apiKey.get("key_id_here");const updatedKey = await reloop.apiKey.update("key_id_here", { name: "New Name" });await reloop.apiKey.delete("key_id_here");// Rotate secret while keeping the same key ID
const rotatedKey = await reloop.apiKey.rotate("key_id_here");
// Pause (disable) — key stops working until re-enabled
await reloop.apiKey.pause("key_id_here");
// equivalent: await reloop.apiKey.disable("key_id_here");
// Resume (enable)
await reloop.apiKey.enable("key_id_here");Add and verify sending domains for your organization.
const domain = await reloop.domain.create({
domain: "send.example.com",
custom_return_path: "inbound",
click_tracking: true,
open_tracking: true,
tls: "opportunistic",
sending_email: true,
receiving_email: true,
});const response = await reloop.domain.list({ page: 1, limit: 10, status: "active" });
console.log(response.domains);const domain = await reloop.domain.get("domain_id_here");
await reloop.domain.update("domain_id_here", {
click_tracking: false,
sending_email: true,
});
await reloop.domain.delete("domain_id_here");const status = await reloop.domain.verify("domain_id_here");
await reloop.domain.forwardDns("domain_id_here", {
email: "admin@example.com",
});Create endpoints, manage status, inspect deliveries, and retry failed attempts.
const webhook = await reloop.webhook.create({
description: "Production notifications",
url: "https://example.com/webhooks/reloop",
events: ["domain.create", "email.sent"],
});
console.log(webhook.secret); // Full secret returned on create onlyconst { webhooks } = await reloop.webhook.list({ page: 1, limit: 10 });
const one = await reloop.webhook.get("wh_id_here");
await reloop.webhook.update("wh_id_here", { maxRetries: 5 });
await reloop.webhook.delete("wh_id_here");await reloop.webhook.pause("wh_id_here");
await reloop.webhook.enable("wh_id_here");
await reloop.webhook.disable("wh_id_here");await reloop.webhook.trigger({
event: "domain.create",
payload: { id: "dom_123", domain: "send.example.com" },
});
const { deliveries } = await reloop.webhook.listDeliveries("wh_id_here", {
status: "failed",
});
await reloop.webhook.retryDelivery("delivery_id_here");Reloop signs each delivery with HMAC-SHA256 (X-Webhook-Signature: t=<unix>,v1=<hex>). Store the signing secret from create() in env — it is not your Reloop API key.
Use the raw request body (request.text() in Next.js). Do not call request.json() before verifying.
// src/app/api/webhook/route.ts
import { NextResponse } from "next/server";
import { WebhookService, WebhookSignatureVerificationError } from "reloop-email";
export async function POST(request: Request) {
try {
const payload = await request.text();
const event = WebhookService.verify({
payload,
headers: {
"x-webhook-signature": request.headers.get("x-webhook-signature"),
"x-webhook-timestamp": request.headers.get("x-webhook-timestamp"),
},
secret: process.env.RELOOP_WEBHOOK_SECRET!,
});
if (event.event === "domain.create") {
console.log("Domain created:", event.payload);
}
return NextResponse.json({ received: true });
} catch (err) {
if (err instanceof WebhookSignatureVerificationError) {
return new NextResponse(err.message, { status: 400 });
}
throw err;
}
}Or with a client instance:
const event = reloop.webhook.verify({ payload, headers, secret });Stripe-style alias:
const event = WebhookService.constructEvent(
payload,
request.headers.get("x-webhook-signature"),
process.env.RELOOP_WEBHOOK_SECRET!,
);Verified event fields: event.id, event.event (type), event.payload, event.timestamp.
The SDK is written in TypeScript and ships type definitions. Import types such as ApiKey, Domain, and ApiKeyListResponse from the package.
import type {
ApiKey,
Domain,
Webhook,
WebhookEvent,
ApiKeyListResponse,
} from "reloop-email";ISC