Skip to content

Best practices for webhooks

Webhooks are HTTP endpoints that you register with a system, allowing that system to inform your application about events by sending HTTP POST requests with event information in the body.

Developers register their applications’ webhook endpoints with Scalekit to listen to events from the directory providers of their enterprise customers. Here are some common best practices developers follow to ensure their apps are secure and performant:

While you can listen to all events from Scalekit, it’s best to subscribe only to the events your app needs. This approach has several benefits:

  • Your app doesn’t have to process every event
  • You can avoid overloading a single execution context by handling every event type

Scalekit sends POST requests to your registered webhook endpoint. To ensure the request is coming from Scalekit and not a malicious actor, you should verify the request using the signing secret found in the Scalekit dashboard > Webhook > Any Endpoint.

Here’s an example of how to verify webhooks using the Svix library:

app.post('/webhook', async (req, res) => {
// Parse the JSON body of the request
const event = await req.json();
// Get headers from the request
const headers = req.headers;
// Secret from Scalekit dashboard > Webhooks
const secret = process.env.SCALEKIT_WEBHOOK_SECRET;
try {
// Verify the webhook payload
await scalekit.verifyWebhookPayload(secret, headers, event);
} catch (error) {
return res.status(400).json({
error: 'Invalid signature',
});
}
});

Make sure to check the event.type before consuming the data received by the webhook endpoint. This ensures that your application relies on accurate information, even if more events are added in the future.

app.post('/webhook', async (req, res) => {
const event = req.body;
// Handle different event types
switch (event.type) {
case 'organization.directory.user_created':
const { email, name } = event.data;
await createUserAccount(email, name);
break;
case 'organization.directory.user_updated':
await updateUserAccount(event.data);
break;
default:
console.log('Unhandled event type:', event.type);
}
return res.status(201).json({
status: 'success',
});
});
async function createUserAccount(email, name) {
// Implement your user creation logic
}

To avoid unnecessary timeouts, respond to the webhook trigger with a response code of 201 and process the event asynchronously.

By following these best practices, you can ensure that your application effectively handles events from Scalekit, maintaining optimal performance and security.

Do not overlook repeated 4xx and 5xx error codes. Instead, verify that your API interactions are correct. For instance, if an endpoint expects a string but receives a numeric value, a validation error should occur. Likewise, trying to access an unauthorized or nonexistent endpoint will trigger a 4xx error.