The DEAF-FIRST Platform webhook system allows you to register and manage webhooks to receive real-time notifications about events in the platform. This replaces the functionality that was previously handled by Xano.
http://localhost:3000/api
Get a list of all registered webhooks.
Endpoint: GET /webhooks
Response:
{
"success": true,
"count": 2,
"webhooks": [
{
"id": "wh_1234567890_abc123",
"name": "Production Webhook",
"url": "https://example.com/webhook",
"events": ["user.created", "user.updated"],
"secret": "***",
"active": true,
"createdAt": "2025-12-05T07:00:00.000Z",
"updatedAt": "2025-12-05T07:00:00.000Z"
}
]
}
Retrieve details of a specific webhook by ID.
Endpoint: GET /webhooks/:id
Response:
{
"success": true,
"webhook": {
"id": "wh_1234567890_abc123",
"name": "Production Webhook",
"url": "https://example.com/webhook",
"events": ["user.created"],
"secret": "***",
"active": true,
"createdAt": "2025-12-05T07:00:00.000Z",
"updatedAt": "2025-12-05T07:00:00.000Z"
}
}
Create a new webhook registration.
Endpoint: POST /webhooks
Request Body:
{
"name": "My Webhook",
"url": "https://example.com/webhook",
"events": ["user.created", "user.updated"],
"secret": "optional-custom-secret"
}
Response:
{
"success": true,
"message": "Webhook registered successfully",
"webhook": {
"id": "wh_1234567890_abc123",
"name": "My Webhook",
"url": "https://example.com/webhook",
"events": ["user.created", "user.updated"],
"secret": "generated-or-custom-secret",
"active": true,
"createdAt": "2025-12-05T07:00:00.000Z",
"updatedAt": "2025-12-05T07:00:00.000Z"
}
}
Update an existing webhook.
Endpoint: PUT /webhooks/:id
Request Body:
{
"name": "Updated Webhook Name",
"url": "https://new-url.com/webhook",
"events": ["user.created", "user.deleted"],
"active": false
}
Response:
{
"success": true,
"message": "Webhook updated successfully",
"webhook": {
"id": "wh_1234567890_abc123",
"name": "Updated Webhook Name",
"url": "https://new-url.com/webhook",
"events": ["user.created", "user.deleted"],
"secret": "***",
"active": false,
"createdAt": "2025-12-05T07:00:00.000Z",
"updatedAt": "2025-12-05T08:00:00.000Z"
}
}
Delete a webhook registration.
Endpoint: DELETE /webhooks/:id
Response:
{
"success": true,
"message": "Webhook deleted successfully"
}
View delivery history for a specific webhook.
Endpoint: GET /webhooks/:id/deliveries
Response:
{
"success": true,
"count": 5,
"deliveries": [
{
"id": "del_1234567890_xyz789",
"webhookId": "wh_1234567890_abc123",
"event": "user.created",
"payload": {
"event": "user.created",
"timestamp": "2025-12-05T07:00:00.000Z",
"data": { "userId": "123", "email": "user@example.com" }
},
"response": {
"status": 200,
"body": "OK"
},
"attempts": 1,
"status": "success",
"timestamp": "2025-12-05T07:00:00.000Z"
}
]
}
Get a list of all available webhook event types.
Endpoint: GET /webhooks/events/types
Response:
{
"success": true,
"count": 12,
"events": [
"user.created",
"user.updated",
"user.deleted",
"auth.login",
"auth.logout",
"document.uploaded",
"document.processed",
"accessibility.request",
"sync.started",
"sync.completed",
"ai.process.started",
"ai.process.completed"
]
}
Manually trigger a webhook event for testing purposes.
Endpoint: POST /webhooks/trigger
Request Body:
{
"event": "user.created",
"data": {
"userId": "123",
"email": "test@example.com",
"name": "Test User"
}
}
Response:
{
"success": true,
"message": "Webhook event triggered successfully"
}
These endpoints receive webhooks from external services like Xano.
Endpoint: POST /incoming-webhooks/:service
Where :service can be:
xano - For Xano webhooksstripe - For Stripe webhookscustom - For custom webhooksHeaders:
X-Webhook-Signature: HMAC signature for verificationX-Webhook-Event: Event typeRequest Body: (varies by service)
{
"event": "record.created",
"data": {
"id": "123",
"table": "users",
"record": { "name": "John Doe" }
}
}
Response:
{
"success": true,
"message": "Webhook received successfully",
"eventId": "evt_1234567890_xyz789"
}
Endpoint: GET /incoming-webhooks/health
Response:
{
"success": true,
"message": "Incoming webhook endpoint is healthy",
"timestamp": "2025-12-05T07:00:00.000Z"
}
All outgoing webhooks include an X-Webhook-Signature header containing an HMAC-SHA256 signature of the payload.
To verify a webhook:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Every webhook delivery includes these headers:
Content-Type: application/jsonX-Webhook-Signature: HMAC signature for verificationX-Webhook-Event: The event type (e.g., “user.created”)X-Webhook-Delivery: Unique delivery IDuser.created - Triggered when a new user is createduser.updated - Triggered when user information is updateduser.deleted - Triggered when a user is deletedauth.login - Triggered when a user logs inauth.logout - Triggered when a user logs outdocument.uploaded - Triggered when a document is uploadeddocument.processed - Triggered when document processing completesaccessibility.request - Triggered when accessibility features are requestedsync.started - Triggered when synchronization beginssync.completed - Triggered when synchronization completesai.process.started - Triggered when AI processing beginsai.process.completed - Triggered when AI processing completes{
"event": "user.created",
"timestamp": "2025-12-05T07:00:00.000Z",
"data": {
"userId": "usr_1234567890",
"email": "user@example.com",
"name": "John Doe",
"preferences": {
"signLanguage": true,
"visualAccessibility": true
}
}
}
If you were previously using Xano webhooks:
POST /webhooks endpoint/incoming-webhooks/xanoAll endpoints return consistent error responses:
{
"success": false,
"error": "Error type",
"message": "Detailed error message"
}
Common HTTP status codes:
200 - Success201 - Created400 - Bad Request404 - Not Found500 - Internal Server ErrorCurrently, there are no rate limits applied to webhook endpoints. In production, consider implementing rate limiting based on your needs.
For issues or questions about the webhook system, please refer to the main documentation or create an issue in the repository.