Guides
First Integration
A worked example — create a resource with the SDK and receive a signed webhook.
This walkthrough builds a minimal but complete integration: you'll create a resource, handle the V1 envelope and errors, and receive + verify a webhook.
Prerequisites
- An API credential (Getting Started).
- A webhook signing secret (created alongside your webhook endpoint in the Developer Portal).
- Node.js 18+.
npm install @emofy/dev-sdk
export EMOFY_API_KEY="sk_live_..."
export EMOFY_WEBHOOK_SECRET="whsec_..."1. Create a resource (idempotently)
Pass an Idempotency-Key so a network retry never double-creates. The SDK
unwraps the V1 envelope and raises a typed EmofyApiError on failures.
import { createEmofyClient, EmofyApiError } from "@emofy/dev-sdk";
import { randomUUID } from "node:crypto";
const client = createEmofyClient({
apiKey: process.env.EMOFY_API_KEY!,
baseUrl: "https://api.emofy.net/api/v1",
});
try {
const { data } = await client.tasks.create(
{ title: "Welcome aboard" },
{ idempotencyKey: randomUUID() },
);
console.log("Created task", data.id);
} catch (err) {
if (err instanceof EmofyApiError) {
// code is the machine-readable V1 error code; requestId correlates with logs.
console.error(err.status, err.code, err.requestId, err.message);
} else {
throw err;
}
}2. Receive the webhook
When the task is created, Emofy POSTs a signed event to your registered
endpoint. Capture the raw body — signature verification depends on the exact
bytes, so never re-serialize the JSON first.
import express from "express";
import { verifyWebhookSignature } from "@emofy/dev-sdk/webhooks";
const app = express();
app.post(
"/webhooks/emofy",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.header("Emofy-Signature");
const valid = verifyWebhookSignature(
req.body, // raw Buffer
signature,
process.env.EMOFY_WEBHOOK_SECRET!,
);
if (!valid) {
return res.status(400).send("invalid signature");
}
const event = JSON.parse(req.body.toString("utf8"));
console.log("Received", event.type);
// Respond 2xx quickly; do heavy work asynchronously so Emofy doesn't retry.
res.status(200).send("ok");
},
);
app.listen(3000);verifyWebhookSignature handles the secret-rotation grace window, enforces a
5-minute replay window, and compares in constant time.
3. Make it production-ready
- Acknowledge fast. Return
2xxwithin a few seconds; offload processing to a queue. Slow responses trigger retries — see Retries & Replay. - Be idempotent on your side too. The same event may be delivered more than once; dedupe on the event id.
- Handle deprecations. The SDK surfaces
onDeprecationcallbacks — see Versioning.