Nimply Developers

Webhooks

Get notified when posts publish, fail, or change

Webhooks push events to your server the moment they happen — no polling. Register an HTTPS endpoint and Nimply will POST a JSON envelope for every subscribed event.

Requires the webhooks:manage scope. Manage endpoints via the API reference.

Events

EventFired when
post.createdA post is created (app or API)
post.updatedA post's content is edited via the API
post.publishedA scheduled post was successfully published
post.failedPublishing was attempted and rejected by the platform
post.deletedA post is deleted via the API
post.approval_requestedA draft is sent for approval
post.approvedAn approver accepts a pending post
post.rejectedAn approver rejects a pending post
channel.disconnectedA channel is removed from the workspace
webhook.testYou call the test endpoint

Payload

Every delivery is a POST with this envelope:

{
  "id": "evt_56e4a1cc-e2c5-459f-b039-445dfef46796",
  "type": "post.published",
  "createdAt": "2026-07-05T13:55:31.246Z",
  "workspaceId": "d8380224-...",
  "data": {
    "postId": "7a245d46-...",
    "channelId": "3e0b9311-...",
    "status": "PUBLISHED",
    "publishedAt": "2026-07-05T13:55:31.000Z",
    "postUrl": "https://...",
    "error": null
  }
}

Headers: X-Nimply-Event (event type), X-Nimply-Delivery (event id, stable across retries), X-Nimply-Signature.

Verifying signatures

Each webhook has a secret (whsec_..., returned when you create it). The signature header is:

X-Nimply-Signature: t=1783259731,v1=71bead50ec1d78af...

v1 is the hex HMAC-SHA256 of "{t}.{rawBody}" using your secret. Verify with a constant-time comparison, and reject timestamps older than a few minutes to prevent replays:

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, header, secret) {
  const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Compute the HMAC over the raw request body — parsing and re-serializing the JSON can change key order and break the signature.

Delivery & retries

  • Respond with any 2xx within 15 seconds to acknowledge.
  • Failed deliveries are retried 5 times with exponential backoff (~1 hour total).
  • After 10 consecutive failed deliveries, the endpoint is auto-disabled (isActive: false). Fix your endpoint, then re-enable it with PATCH /v1/webhooks/{id} — that also resets the failure counter.
  • Deliveries can arrive out of order and (rarely) more than once — deduplicate by the envelope id.

Testing

POST /v1/webhooks/{id}/test sends a webhook.test event so you can verify connectivity and your signature check before going live.

On this page