Webhook Documentation
Real-time notifications for schema events
What are Webhooks?
Webhooks allow your application to receive real-time notifications when schemas are generated, updated, or when errors occur. Instead of polling our API, webhooks push data to your server instantly.
Platform Support
Works with any webhook-compatible platform
Our webhooks use a hybrid payload format that works with any platform. The payload includes both structured data for custom integrations and rich formatting for messaging platforms.
Slack
Use your Slack Incoming Webhook URL. Messages will display with rich formatting and blocks.
Discord
Use your Discord Webhook URL. The text field provides a clean summary message.
Custom Endpoint
Use any HTTP endpoint. Parse the structured JSON payload for your custom integration.
Setting Up Webhooks
Configure your webhook endpoint in 3 simple steps
Create a webhook endpoint
Create an HTTP endpoint on your server that can receive POST requests.
Configure in Project Settings
Go to Project Settings > Webhooks and enter your endpoint URL and optional secret.
Test your webhook
Use the "Test Webhook" button to verify your endpoint is working correctly.
Webhook Events
Events that trigger webhook notifications
schema.generatedTriggered when a schema is successfully generated or regenerated for a page.
schema.failedTriggered when schema generation fails. Includes error details in the payload.
scan.completedTriggered when a website scan (crawl) completes successfully. Includes information about scanned URLs and newly discovered pages.
scan.failedTriggered when a website scan (crawl) fails. Includes error details about what went wrong.
project.email_notifications.toggledTriggered when an email notification setting for a project is changed.
project.api_key.generatedTriggered when a new API key is generated for a project.
project.api_key.deletedTriggered when an API key is deleted from a project.
project.scheduled_regeneration.toggledTriggered when the scheduled regeneration setting for a project is changed.
project.webhook.toggledTriggered when the main webhook enable/disable switch for a project is used.
job.completedTriggered when any background job associated with the project completes successfully.
job.failedTriggered when any background job associated with the project fails.
Webhook Payload
Structure of the data sent to your endpoint
{
"event": "string", // Event type (e.g., "schema.generated", "scan.completed")
"timestamp": "string", // ISO 8601 format (e.g., "2024-01-15T10:30:00.000Z")
"projectId": "string", // ID of the project
"userId": "string", // ID of the user who owns the project
"text": "string", // Plain text summary for all platforms
// Optional fields, depending on the event type
"jobId"?: "string", // ID of the associated job, if any
"pageId"?: "string", // ID of the associated page, if any
"status"?: "completed" | "failed", // Status for job-related events
"data"?: { // Event-specific data
// Example for "schema.generated" / "schema.failed"
"pageUrl"?: "string",
"schemaVersionId"?: "string",
"error"?: "string", // For failed events
// Example for "scan.completed" / "scan.failed"
"baseUrl"?: "string",
"error"?: "string", // For failed events
// Example for "project.email_notifications.toggled"
"setting"?: "string", // e.g., "jobCompletion"
"enabled"?: boolean, // Setting state
// Example for "project.api_key.generated" / "project.api_key.deleted"
"apiKeyName"?: "string",
"apiKeyId"?: "string",
"lastCharacters"?: "string",
// Example for "project.scheduled_regeneration.toggled"
"frequency"?: "weekly" | "monthly",
// Add any event-specific fields
[key: string]: any
},
// Optional: Slack-specific rich formatting (ignored by non-Slack platforms)
"blocks"?: Array<{ // Slack message blocks (optional, Slack only)
type: string,
text?: object,
fields?: Array<any>
}>
}Security & Signature Verification
Verify webhook authenticity using HMAC signatures
If you configure a webhook secret, we'll sign each webhook with an HMAC SHA-256 signature sent in the X-Webhook-Signature header.
Node.js Example:
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)
);
}
// In your webhook handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, YOUR_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook...
res.status(200).send('OK');
});Best Practices
- Always verify the signature if you configured a secret
- Respond with a 2xx status code quickly (within 5 seconds)
- Process webhook data asynchronously (use a queue)
- Implement idempotency to handle duplicate deliveries
- Use HTTPS endpoints for production
Troubleshooting
Webhook not receiving events?
- Verify your endpoint is publicly accessible
- Check that your server responds with 2xx status codes
- Ensure your firewall allows incoming requests
- Use the "Test Webhook" button to verify configuration
Signature verification failing?
- Ensure you're using the raw request body (not parsed JSON)
- Check that your secret matches exactly (no extra spaces)
- Verify you're using HMAC SHA-256 algorithm