docs/platform/developer/webhooks.mdx
Webhooks makes it possible for your external systems to receive real-time notifications when specific events occur within your Novu account. They are POST requests sent to a pre-determined endpoint that you configure.
<Note> Outbound webhooks feature is only available in the [Team and Enterprise plans](https://novu.co/pricing). </Note>You provide Novu with a URL (endpoint), and we send a JSON payload to that URL whenever an event happens, such as a workflow update or message delivery.
For example, to receive updates at https://api.yourservice.com/novu/webhook/, you must configure this as your endpoint. Your server then acknowledges receipt by returning a 2xx status code (200-299).
To start listening to messages, you must register your endpoint in the Novu dashboard.
When adding or editing an endpoint, you can utilize the advanced configuration option to fine-tune how Novu communicates with your server.
After you've added an endpoint, you can test it to be sure it's working. To do this:
After sending an example event, you can view the message payload, all of the message attempts, and whether it succeeded or failed.
You must verify that the requests hitting your endpoint are actually from Novu and not a malicious actor.
Novu signs webhook requests so you can verify that payloads were sent by Novu. Official libraries are available for verifying signatures.
import { Webhook } from "svix";
const secret = "YOUR_WEBHOOK_SECRET_KEY";
// These were all sent from the server
const headers = {
"webhook-id": "msg_p5jXN8AQM9LWM0D4loKWxJek",
"webhook-timestamp": "1614265330",
"webhook-signature": "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=",
};
const payload = '{"test": 2432232314}';
const wh = new Webhook(secret);
// Throws on error, returns the verified content on success
const verifiedPayload = wh.verify(payload, headers);
See the library documentation for more instructions and examples of how to verify signatures in other languages.
When your service experiences downtime or your endpoint is misconfigured, you can replay failed messages once you are back online.
When an event cannot be delivered, Novu retries using exponential backoff. Each message is attempted based on the following schedule, where each period is started following the failure of the preceding attempt:
For example, an attempt that fails three times before eventually succeeding will be delivered roughly 35 minutes and 5 seconds following the first attempt.
You can find all the historical delivery attempts for each webhook endpoint in the webhook activity tab of that endpoint.
When your endpoint is unavailable, Novu keeps retrying according to the retry schedule. When all attempts fail for 5 days consecutively, the endpoint will be disabled and you have to manually re-enable it.
To resend an individual event:
This operation causes all failed messages to a particular endpoint to be resent. To do this:
This operation causes all messages that were never attempted for a particular endpoint to be resent. To do this:
Endpoints can be manually enabled or disabled at any time. Novu also automatically disables an endpoint when all deliveries fail for 5 consecutive days.
To enable or disable an endpoint:
Deleting an endpoint immediately stops all future delivery attempts and removes the configuration from your account. This action is permanent.
To delete an endpoint:
There are some common reasons why your webhook endpoint is failing:
Using different implementations to convert JSON payloads into strings can produce different string representations of the JSON object, which can lead to discrepancies when verifying the signature.
Verify the payload exactly as it was sent, byte-for-byte or string-for-string, to ensure accurate verification.
When Novu receives a response with a 2xx status code, it is interpreted as a successful delivery even regardless of the response payload. Make sure to use the right response status codes so Novu knows when messages are supposed to succeed or fail.
Novu considers all messages that fails to send a response within 15 seconds as a failed message.
For cases where your endpoint is processing complicated workflows, you can have your endpoint receive the message and add it to a queue to be processed asynchronously to avoid getting timed out.
1. Verify the webhook signature using the official verification library
2. Use HTTPS for your endpoint URL
3. Implement rate limiting to prevent abuse
4. Keep your webhook secret secure and rotate it periodically