Node.js SDK
Send messages from your JavaScript or TypeScript backend.
Use it on your server with Node.js 22+, ESM or CommonJS.
Get started
Install
npm install @appkeeprhq/nodeFollow Quickstart to create a signups channel and set APPKEEPR_API_TOKEN.
Send a message
import { Appkeepr } from "@appkeeprhq/node";
const token = process.env.APPKEEPR_API_TOKEN;
if (!token) throw new Error("Set APPKEEPR_API_TOKEN.");
const appkeepr = new Appkeepr({ token });
const result = await appkeepr.messages.send(
{
channel: "signups",
body: "Ada created an account.",
title: "New signup",
icon: "👋",
},
{ idempotencyKey: "signup-1042" },
);
console.log(result.messageId, result.outcome);send returns {messageId, outcome}. See the API reference for all message fields.
Optional project
Create a checkout project in Projects, then use it as the default:
const checkout = new Appkeepr({ token, project: "checkout" });
await checkout.messages.send({ channel: "signups", body: "Ada signed up." });
await checkout.messages.send({
channel: "signups",
body: "A signup was recorded.",
project: null,
});Set project per message to override the default, or use null to leave it out.
Notification sounds
Choose a preset for each message:
await appkeepr.messages.send(
{ channel: "sales", body: "Ada upgraded to Pro.", sound: "cash" },
{ idempotencyKey: "purchase-1044" },
);Leave out sound for the default tone, or use "none" for no sound. See Notification sounds for all presets and device support.
Timeouts and errors
Requests time out after 10 seconds. Pass an abort signal for a shorter timeout:
import { AppkeeprError } from "@appkeeprhq/node";
try {
await appkeepr.messages.send(
{ channel: "signups", body: "A new account was created." },
{ idempotencyKey: "signup-1043", signal: AbortSignal.timeout(3_000) },
);
} catch (error) {
if (error instanceof AppkeeprError) {
console.error(error.status, error.code, error.message);
// Honor error.retryAfterSeconds when present.
} else {
throw error; // Network or abort error.
}
}Retry safely
The SDK doesn't retry automatically. A timeout may still mean your message arrived, so retry with the same idempotency key and content.
Next.js
Use a Node.js server module with a private environment variable:
import "server-only";
import { Appkeepr } from "@appkeeprhq/node";
export function getAppkeepr() {
const token = process.env.APPKEEPR_API_TOKEN;
if (!token) throw new Error("Set APPKEEPR_API_TOKEN.");
return new Appkeepr({ token });
}Call and await getAppkeepr().messages.send(...) from a Route Handler, Server Action or server job. Use the Node.js runtime and keep your token out of NEXT_PUBLIC_ variables.