Outgoing Webhooks
Receive real-time HTTP notifications when events occur in your Crove documents.
Outgoing Webhooks
Outgoing webhooks send HTTP POST requests to your server when events happen in Crove. This lets you react to document events in real-time without polling the API.
Setting up a webhook
- Go to Settings > Webhooks
- Click Create Webhook
- Configure the webhook:
| Field | Description |
|---|---|
| Template | Which template triggers this webhook |
| URL | Your server endpoint that receives the webhook |
| Method | HTTP method (POST, PUT, PATCH) |
| Events | Which events trigger the webhook |
| Headers | Custom HTTP headers (e.g., authentication) |
| Active | Enable/disable the webhook |
- Click Save
Payload format
All webhooks send a JSON payload:
{
"event": "document.completed",
"documentId": "doc_abc123",
"templateId": "tmpl_xyz789",
"timestamp": "2026-02-18T14:30:00Z",
"data": {
"documentName": "Contract - Acme Corp",
"completed": true,
"responseData": {
"clientName": "Acme Corporation",
"contractAmount": 50000
}
}
}Common payload fields
| Field | Type | Description |
|---|---|---|
event | string | Event type (e.g., document.completed) |
documentId | string | ID of the affected document |
templateId | string | ID of the template |
timestamp | string | ISO 8601 timestamp |
data | object | Event-specific payload data |
Custom headers
Add custom headers to authenticate webhook requests on your server:
Authorization: Bearer your_secret_token
X-Custom-Header: custom_valueThis lets your server verify that incoming requests are genuinely from Crove.
Retry logic
If your server doesn't respond with a 2xx status code, Crove retries the webhook:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
After 3 failed attempts, the webhook delivery is marked as failed. You can view delivery logs in Settings > Webhooks.
Delivery logs
Each webhook has a delivery log showing:
- Delivery timestamp
- HTTP status code returned by your server
- Response time
- Success/failure status
- Payload that was sent
Use delivery logs to debug integration issues.
Testing webhooks
Before going live, test your webhook setup:
- Use a service like webhook.site to get a temporary URL
- Set the test URL as your webhook endpoint
- Trigger an event (create a document, submit a response)
- Inspect the payload on webhook.site
- Once verified, update to your production URL
Example: Slack notification
Send a Slack message when a document is completed:
// Your webhook endpoint
app.post('/webhooks/crove', (req, res) => {
const { event, data } = req.body;
if (event === 'document.completed') {
// Send Slack notification
await fetch(SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `Document "${data.documentName}" has been completed!`
})
});
}
res.status(200).json({ received: true });
});Example: CRM sync
Update your CRM when a form response is submitted:
app.post('/webhooks/crove', async (req, res) => {
const { event, data } = req.body;
if (event === 'respondent.submitted') {
// Sync data to your CRM
await crmClient.updateContact({
email: data.respondentEmail,
fields: data.responseData
});
}
res.status(200).json({ received: true });
});Best practices
- Respond quickly — Return a
200status immediately, then process the data asynchronously - Verify the source — Use custom headers to authenticate webhook requests
- Handle duplicates — Webhooks may be delivered more than once; use
documentId+eventas an idempotency key - Log everything — Store webhook payloads for debugging and audit purposes
- Use HTTPS — Always use an HTTPS endpoint for webhook URLs