Webhooks
Receive real-time event notifications via HTTP — setup, event types, payload format, and HMAC-SHA256 signature verification.
Overview
Webhooks let you receive HTTP POST notifications when events occur in ProBeya. Instead of polling the API for changes, register a webhook endpoint and ProBeya will push events to you in real time — typically within 1–3 seconds of the event occurring.
Use webhooks to:
- Sync ProBeya data with external systems (ERP, MES, QMS)
- Trigger CI/CD pipelines when items change status
- Build custom alerting and notification flows
- Update external dashboards when KPIs are recorded
Setting Up a Webhook
Via the Dashboard
- Navigate to Settings > Integrations > Webhooks
- Click + Create Webhook
- Enter the endpoint URL (must be HTTPS in production)
- Select the events you want to receive
- Set a signing secret (strongly recommended for payload verification)
- Click Create
Via the API
curl -X POST "https://acme.probeya.com/api/v1/webhooks" \
-H "Authorization: Bearer probeya_sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/probeya",
"events": ["item.created", "item.updated", "kpi.value_entered"],
"secret": "whsec_your_signing_secret_here",
"description": "Sync to SAP"
}'
Response:
{
"data": {
"id": "whk_clx9abc123",
"url": "https://your-server.com/webhooks/probeya",
"events": ["item.created", "item.updated", "kpi.value_entered"],
"active": true,
"createdAt": "2026-03-19T14:30:00.000Z"
}
}
Event Types
Items
| Event | Trigger |
|---|---|
item.created | A new item is created on any board |
item.updated | An item’s fields, status, or assignment change |
item.deleted | An item is permanently deleted |
item.moved | An item is moved to a different group or board |
item.commented | A comment is added to an item |
KPIs
| Event | Trigger |
|---|---|
kpi.value_entered | A KPI measurement value is recorded |
kpi.target_breached | A KPI value crosses its target threshold (red/amber) |
kpi.created | A new KPI definition is created |
kpi.updated | A KPI definition is modified |
Actions
| Event | Trigger |
|---|---|
action.created | A new action item is created |
action.updated | An action’s status, owner, or due date changes |
action.escalated | An overdue action is escalated to a higher tier |
action.completed | An action is marked as completed |
Projects & Boards
| Event | Trigger |
|---|---|
project.created | A new project is created |
project.deleted | A project is deleted |
board.created | A new board is created within a project |
board.updated | A board’s configuration changes |
board.deleted | A board is deleted |
Members
| Event | Trigger |
|---|---|
member.invited | A member is invited to the organization |
member.joined | An invited member accepts and joins |
member.removed | A member is removed from the organization |
member.role_changed | A member’s role is changed |
Forms
| Event | Trigger |
|---|---|
form.submitted | A form receives a submission |
form.published | A form is published and made available |
Meetings
| Event | Trigger |
|---|---|
meeting.started | A tier meeting begins |
meeting.completed | A tier meeting is concluded |
Payload Format
All webhook payloads follow a consistent structure:
{
"id": "evt_clx9abc123def",
"event": "item.updated",
"timestamp": "2026-03-19T14:30:00.000Z",
"apiVersion": "v1",
"organizationId": "org_clx9abc123",
"data": {
"item": {
"id": "itm_clx9abc123",
"name": "Update SOP-42 revision 3",
"boardId": "brd_clx9xyz789",
"groupId": "grp_clx9abc123",
"status": "done",
"priority": "high",
"assigneeId": "usr_clx9def456"
},
"changes": {
"status": {
"old": "in_progress",
"new": "done"
}
},
"actor": {
"id": "usr_clx9def456",
"email": "[email protected]"
}
}
}
Payload Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique event ID — use for idempotent processing |
event | string | Event type (e.g., item.updated) |
timestamp | string | ISO 8601 timestamp of when the event occurred |
apiVersion | string | API version that generated the event |
organizationId | string | Organization where the event occurred |
data | object | Event-specific payload (varies by event type) |
data.changes | object | For .updated events, the old and new values of changed fields |
data.actor | object | The user who triggered the event |
Signature Verification
If you provided a secret when creating the webhook, every request includes an X-ProBeya-Signature header. Always verify this signature to confirm the payload was sent by ProBeya and was not tampered with in transit.
The signature is computed as sha256=<hex-encoded HMAC-SHA256 of the raw request body using your secret as the key>.
Always use timing-safe comparison (timingSafeEqual in Node.js, hmac.compare_digest in Python) when verifying signatures. Standard string comparison (===, ==) is vulnerable to timing attacks that could allow an attacker to reconstruct the expected signature.
Retry Policy
If your endpoint returns a non-2xx status code or does not respond within 10 seconds, ProBeya retries delivery with exponential backoff:
| Attempt | Delay After Failure |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 12 hours |
After 5 failed attempts, the webhook is marked as failed and no further deliveries are attempted. You can:
- Fix your endpoint and click Retry Failed in the dashboard
- View failed deliveries in Settings > Integrations > Webhooks > [name] > Logs
Return a 200 OK response as quickly as possible. Process the event asynchronously (e.g., push to a queue) rather than performing slow operations synchronously — a response timeout counts as a failure.
Idempotent Processing
Webhook deliveries may occasionally be duplicated (e.g., during retries or network issues). Use the id field in the event payload to implement idempotent handling:
const processedEvents = new Set(); // In production, use Redis or a database
app.post("/webhooks/probeya", (req, res) => {
const event = req.body;
// Skip events we have already processed
if (processedEvents.has(event.id)) {
return res.status(200).json({ received: true, duplicate: true });
}
processedEvents.add(event.id);
// Process the event...
res.status(200).json({ received: true });
});
Managing Webhooks
List Webhooks
curl "https://acme.probeya.com/api/v1/webhooks" \
-H "Authorization: Bearer probeya_sk_live_abc123..."
Update a Webhook
curl -X PATCH "https://acme.probeya.com/api/v1/webhooks/whk_clx9abc123" \
-H "Authorization: Bearer probeya_sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"events": ["item.created", "item.updated", "item.deleted"],
"active": true
}'
Delete a Webhook
curl -X DELETE "https://acme.probeya.com/api/v1/webhooks/whk_clx9abc123" \
-H "Authorization: Bearer probeya_sk_live_abc123..."
Was this page helpful?