Webhooks
Stay informed about critical events in your Duro library with real-time webhook notifications.
Overview
Duro webhooks enable your applications to receive real-time notifications when important events occur in your library. Instead of continuously polling for changes, webhooks push event notifications to your specified endpoints, allowing you to build responsive integrations that react immediately to data changes.
Key Benefits
Real-time updates - Get notified instantly when data changes
Efficient integration - No need for constant API polling
Selective subscriptions - Choose only the events you care about
Reliable delivery - Built-in retry mechanisms ensure event delivery
How Webhooks Work
Event occurs - Something happens in Duro (e.g., a component is updated)
Notification sent - Duro sends a lightweight payload to your webhook URL
Fetch full data - Your application uses the provided metadata to fetch complete details via GraphQL as needed
This pattern keeps webhook payloads small and fast while giving you access to all the data you need.
Available Events
Phase 1: Item Events
ITEM_CREATE
- New component, product, or assembly createdITEM_UPDATE
- Existing item modifiedITEM_DELETE
- Item removed from library
Phase 2: Change Order Events
CO_OPEN
- New change order createdCO_UPDATE
- Change order details modifiedCO_DELETE
- Change order removedCO_STAGE_TRANSITION
- Change order moves between workflow stagesCO_STAGE_REVIEWER_DECISION
- Individual reviewer approves/rejectsCO_RESOLUTION
- Change order fully approved, rejected, or withdrawn
Phase 3: Configuration Events (Coming Soon)
Category updates and other configuration changes
Setting Up Webhooks
Create a Webhook
mutation CreateWebhook {
webhooks {
create(input: {
name: "Production System Sync"
description: "Sync component updates to our ERP system"
url: "https://api.mycompany.com/duro-webhook"
events: [ITEM_CREATE, ITEM_UPDATE, CO_RESOLUTION]
isEnabled: true
}) {
id
name
url
events
}
}
}
List Your Webhooks
query GetMyWebhooks {
webhooks {
get {
id
name
description
url
events
isEnabled
createdAt
}
}
}
Update a Webhook
mutation UpdateWebhook {
webhooks {
update(
filter: { ids: ["webhook_123"] }
input: {
events: [ITEM_CREATE, ITEM_UPDATE, ITEM_DELETE]
isEnabled: false
}
) {
id
events
isEnabled
}
}
}
Webhook Payloads
All webhook notifications follow a consistent structure:
{
"id": "evt_abc123",
"webhook_id": "webhook_xyz789",
"event": "ITEM_UPDATE",
"created_at": "2024-12-20T10:30:00Z",
"data": {
"item_id": "comp_123456"
}
}
Event-Specific Data
Item Events
{
"event": "ITEM_CREATE",
"data": {
"item_id": "comp_789012"
}
}
Change Order Stage Transition
{
"event": "CO_STAGE_TRANSITION",
"data": {
"change_order_id": "co_345678",
"stage_id": "stage_901234",
"decision": "approved"
}
}
Change Order Resolution
{
"event": "CO_RESOLUTION",
"data": {
"change_order_id": "co_345678",
"resolution": "approved"
}
}
Fetching Full Resource Data
After receiving a webhook notification, use the provided IDs to fetch complete resource details:
Fetch Item Details
query GetItemDetails($itemId: ID!) {
components {
get(filter: { ids: [$itemId] }) {
connection {
edges {
node {
id
cpn
name
description
revision
status
category {
name
code
}
}
}
}
}
}
}
Fetch Change Order Details
query GetChangeOrderDetails($coId: ID!) {
changeOrders {
get(filter: { ids: [$coId] }) {
connection {
edges {
node {
id
name
description
status
resolution
stages {
id
name
decisionState
reviewers {
id
decisionState
user {
name
primaryEmail
}
}
}
}
}
}
}
}
}
Security
Webhook Signatures
Each webhook request includes a signature header for verification:
X-Duro-Signature: sha256=abc123...
Verify signatures using your webhook's signing secret:
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expected}` === signature;
}
Best Practices
Use HTTPS - Always use secure HTTPS endpoints
Verify signatures - Validate every webhook request
Respond quickly - Return 200 OK immediately, process asynchronously
Handle retries - Duro retries failed deliveries with exponential backoff
Monitor health - Track webhook success rates and response times
Monitoring Webhook Activity
Query your webhook logs to monitor delivery status:
query GetWebhookLogs {
webhooks {
getLogs(
webhookID: "webhook_123"
orderBy: [{ createdAt: DESC }]
) {
connection(first: 20) {
edges {
node {
id
event
metadata
responseCode
isAcknowledged
createdAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
Common Use Cases
ERP Integration
Sync component and BOM changes to your ERP system in real-time:
app.post('/webhook/duro', async (req, res) => {
// Verify webhook signature
if (!verifySignature(req)) {
return res.status(401).send('Unauthorized');
}
// Acknowledge receipt immediately
res.status(200).send('OK');
// Process asynchronously
const { event, data } = req.body;
if (event === 'ITEM_UPDATE') {
const item = await fetchItemFromDuro(data.item_id);
await syncToERP(item);
}
});
Slack Notifications
Alert your team about important changes:
if (event === 'CO_RESOLUTION') {
const co = await fetchChangeOrder(data.change_order_id);
await postToSlack({
text: `Change Order "${co.name}" was ${data.resolution}!`,
color: data.resolution === 'approved' ? 'good' : 'warning'
});
}
Automated Workflows
Trigger downstream processes based on lifecycle events:
if (event === 'CO_STAGE_TRANSITION' && data.decision === 'approved') {
// Automatically create manufacturing work orders
// when engineering approval is complete
await createWorkOrder(data.change_order_id);
}
Error Handling
Duro webhooks include automatic retry logic:
Retry schedule: 5s, 30s, 2m, 10m, 30m, 1h, 2h, 4h
Success codes: 200-299
Failure codes: All others trigger retries
Your endpoint should:
Return 200 immediately to acknowledge receipt
Process the webhook asynchronously
Log failures for debugging
Implement idempotency to handle duplicate deliveries
Next Steps
Explore our GraphQL API for fetching full resource data
Review Authentication for securing your webhook endpoints
Learn about Error Handling patterns for robust integrations
Last updated