Webhooks API
Receive real-time notifications for events.
List Webhooks
GET /webhooksResponse
{
"data": [
{
"id": "hook_abc123",
"url": "https://example.com/webhook",
"events": ["machine.offline", "command.failed"],
"enabled": true,
"created_at": "2024-01-15T10:30:00Z"
}
]
}Create Webhook
POST /webhooksRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Webhook endpoint URL |
events | array | Yes | Events to subscribe to |
secret | string | No | Signing secret |
enabled | boolean | No | Default: true |
Example
curl -X POST https://api.cmdop.com/v1/webhooks \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhook",
"events": ["machine.offline", "command.failed", "schedule.failed"],
"secret": "your-secret-key"
}'Response
{
"data": {
"id": "hook_abc123",
"url": "https://example.com/webhook",
"events": ["machine.offline", "command.failed", "schedule.failed"],
"enabled": true,
"created_at": "2024-01-20T15:45:00Z"
}
}Update Webhook
PATCH /webhooks/:idRequest Body
{
"events": ["machine.offline"],
"enabled": false
}Delete Webhook
DELETE /webhooks/:idEvent Types
| Event | Description |
|---|---|
machine.online | Machine came online |
machine.offline | Machine went offline |
command.completed | Command finished |
command.failed | Command failed (non-zero exit) |
schedule.completed | Scheduled task completed |
schedule.failed | Scheduled task failed |
file.uploaded | File uploaded |
Webhook Payload
Webhooks are sent as POST requests with JSON body:
{
"id": "evt_xyz789",
"type": "machine.offline",
"timestamp": "2024-01-20T15:45:00Z",
"data": {
"machine_id": "mach_abc123",
"machine_name": "production-server",
"last_seen": "2024-01-20T15:44:00Z"
}
}Signature Verification
If you provided a secret, verify the signature:
X-Cmdop-Signature: sha256=abc123...Node.js Example
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expected}` === signature;
}
// In your handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-cmdop-signature'];
const valid = verifySignature(req.rawBody, signature, process.env.WEBHOOK_SECRET);
if (!valid) {
return res.status(401).send('Invalid signature');
}
// Process webhook
const event = req.body;
console.log(`Received ${event.type}`);
res.status(200).send('OK');
});Retry Policy
Failed deliveries are retried:
- 3 attempts
- Exponential backoff: 1min, 5min, 30min
- After all retries, webhook is disabled
Test Webhook
POST /webhooks/:id/testSends a test event to your endpoint:
{
"id": "evt_test",
"type": "test",
"timestamp": "2024-01-20T15:45:00Z",
"data": {
"message": "This is a test webhook"
}
}