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
| Event | Fired when |
|---|---|
post.created | A post is created (app or API) |
post.updated | A post's content is edited via the API |
post.published | A scheduled post was successfully published |
post.failed | Publishing was attempted and rejected by the platform |
post.deleted | A post is deleted via the API |
post.approval_requested | A draft is sent for approval |
post.approved | An approver accepts a pending post |
post.rejected | An approver rejects a pending post |
channel.disconnected | A channel is removed from the workspace |
webhook.test | You 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
2xxwithin 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 withPATCH /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.