EmofyEmofy Developers
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 2xx within 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 onDeprecation callbacks — see Versioning.

Next steps

On this page