Stickermaker.dev Docs
Guides

Implementing Webhooks

Receive server-to-server notifications when your stickers are ready.

Webhooks allow the Sticker Maker API to notify your application when a job changes state, rather than requiring you to poll for updates.

Configuring Webhooks

You can register webhook endpoints via the Dashboard or using the API.

Registration via API

curl -X POST https://api.stickermaker.dev/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/api/webhooks/stickermaker",
    "events": ["job.completed", "job.failed"]
  }'

Payload Format

We send a POST request to your configured URL with a JSON payload.

Example Payload

{
  "id": "evt_123456",
  "object": "event",
  "type": "job.completed",
  "created": 1703600000,
  "data": {
    "jobId": "job_abc123",
    "status": "completed",
    "result": {
      "stickerUrl": "https://media.stickermaker.dev/stickers/abc123.webp",
      "format": "webp",
      "size": 512
    }
  }
}

Security & Verification

To verify that the request actually came from us, we include a signature in the X-Sticker-Signature header.

Verifying Signatures

The signature is an HMAC-SHA256 hash of the request body using your webhook secret.

import crypto from "crypto";

function verifyWebhook(payload, signatureHeader, secret) {
  const [timestamp, signature] = signatureHeader.split(",");

  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${payload}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature),
  );
}

Always verify signatures! Failing to verify the signature could allow attackers to send fake event data to your application.

Best Practices

  1. Idempotency: Your webhook handler should be idempotent. We may retry delivery if your server times out, so ensure processing the same event ID twice doesn't break your app.
  2. Respond Quickly: Return a 200 OK as soon as you receive the webhook, before doing any heavy processing. If you take longer than 5 seconds, we may consider it a timeout and retry.
  3. Use a Queue: For high-volume applications, push the webhook payload to a queue (like Redis or SQS) and process it asynchronously.

On this page