Skip to Content
DocsAPIWebhooks

Webhooks API

TL;DR

The Webhooks API lets you receive real-time HTTP POST notifications for session, machine, command, and file events. Create webhooks with POST /webhooks, subscribe to specific event types, verify payloads using HMAC-SHA256 signatures, and test endpoints before going live. Failed deliveries are retried 3 times with exponential backoff.

The Webhooks API is planned and not yet available — the relay does not currently expose a /webhooks surface. This page documents the intended contract (endpoints, event types, signature scheme, retry policy) so integrations can be designed against it ahead of time. For live event delivery today, use the realtime channels described in the SDKs.

How do I list webhooks?

GET /webhooks

Response

{ "data": [ { "id": "hook_abc123", "url": "https://example.com/webhook", "events": ["machine.offline", "command.failed"], "enabled": true, "created_at": "2024-01-15T10:30:00Z" } ] }

How do I create a webhook?

POST /webhooks

Request Body

FieldTypeRequiredDescription
urlstringYesWebhook endpoint URL
eventsarrayYesEvents to subscribe to
secretstringNoSigning secret
enabledbooleanNoDefault: 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" } }

How do I update a webhook?

PATCH /webhooks/:id

Request Body

{ "events": ["machine.offline"], "enabled": false }

How do I delete a webhook?

DELETE /webhooks/:id

What event types are available?

Session Events

EventDescription
session.createdNew session created
session.connectedAgent connected to session
session.client_attachedClient attached to session
session.client_detachedClient detached from session
session.grace_periodSession entered grace period
session.disconnectedSession ended

Machine Events

EventDescription
machine.onlineMachine came online
machine.offlineMachine went offline
machine.registeredNew machine registered

Command Events

EventDescription
command.startedCommand started executing
command.completedCommand finished successfully
command.failedCommand failed (non-zero exit)
command.timeoutCommand timed out

File Events

EventDescription
file.uploadedFile uploaded
file.downloadedFile downloaded
file.deletedFile deleted

What does the webhook payload look like?

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" } }

How do I verify webhook signatures?

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'); });

What is the retry policy?

Failed deliveries are retried:

  • 3 attempts
  • Exponential backoff: 1min, 5min, 30min
  • After all retries, webhook is disabled

How do I test a webhook?

POST /webhooks/:id/test

Sends a test event to your endpoint:

{ "id": "evt_test", "type": "test", "timestamp": "2024-01-20T15:45:00Z", "data": { "message": "This is a test webhook" } }