Webhooks
Receive external events, inspect webhook request logs, and manage webhook endpoints through the DRAGOPS API.
Webhooks allow external systems to trigger pattern executions by sending HTTP requests to unique URLs. Each On Webhook node in a deployed pattern receives its own endpoint with an independent signing secret.
Webhook ingestion
POST /webhooks/:webhookId
Send an event to a webhook endpoint. This is the primary entry point for external systems to trigger pattern executions.
No authentication token required. Webhook endpoints use HMAC-SHA256 signature validation instead.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
webhookId | string | Yes | Webhook endpoint ID |
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | Must be application/json |
X-Webhook-Signature | Yes | HMAC-SHA256 hex digest of the request body, signed with the webhook secret |
X-Idempotency-Key | No | Unique key to prevent duplicate processing (24-hour window) |
X-Request-Id | No | Request tracking ID (also used for idempotency if X-Idempotency-Key is absent) |
Request body
Send any valid JSON payload. The pattern receives the full request including headers, body, query parameters, and HTTP method.
{
"action": "opened",
"repository": "my-org/my-repo",
"sender": "jane-smith"
}Signing the request
Compute an HMAC-SHA256 signature of the raw request body using the webhook secret and include it in the X-Webhook-Signature header:
echo -n '{"action":"opened"}' | openssl dgst -sha256 -hmac 'your-webhook-secret'Response (active deployment)
202 Accepted
{
"status": "accepted",
"runId": "run_abc123"
}Response (no active deployment)
When the pattern is not deployed, the webhook captures the event for testing but does not execute:
202 Accepted
{
"status": "captured",
"message": "Event captured for testing"
}Response (synchronous mode)
When the deployment uses synchronous webhook responses, the endpoint holds the connection until the pattern completes and returns a custom response from the Respond To Webhook node:
{
"message": "Processed successfully",
"ticketId": "TKT-1234"
}Response (duplicate request)
When an X-Idempotency-Key header matches a previously processed request:
{
"status": "duplicate",
"message": "Event already processed"
}Errors
| Status | Description |
|---|---|
401 | Missing or invalid HMAC signature |
404 | Webhook endpoint not found |
429 | Rate limit exceeded (100 requests per minute per IP) |
Webhook verification
GET /webhooks/:webhookId
Verify that a webhook endpoint exists and is active. Some external systems send a GET request as a challenge-response verification before sending events.
No authentication token required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
webhookId | string | Yes | Webhook endpoint ID |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
challenge | string | No | Challenge value to echo back |
hub.challenge | string | No | Alternative challenge parameter (Facebook/Meta format) |
Response (active)
{
"status": "ok",
"webhookId": "whk_abc123"
}Response (with challenge)
Returns the challenge value as plain text:
abc123challengeErrors
| Status | Description |
|---|---|
404 | Webhook endpoint not found or not active |
List pattern webhook endpoints
GET /api/patterns/:id/webhooks
Return all webhook endpoints associated with a pattern, regardless of deployment status. Webhook URLs are stable across undeploy/redeploy cycles.
Authentication required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pattern ID |
Response
{
"success": true,
"data": {
"endpoints": [
{
"webhookId": "whk_abc123",
"webhookUrl": "https://your-domain/webhooks/whk_abc123",
"webhookAlias": "github-events",
"nodeId": "node_1",
"webhookSecret": "a1b2c3d4e5...",
"status": "active"
},
{
"webhookId": "whk_def456",
"webhookUrl": "https://your-domain/webhooks/whk_def456",
"webhookAlias": "slack-commands",
"nodeId": "node_2",
"webhookSecret": "f6g7h8i9j0...",
"status": "inactive"
}
]
}
}The status field is active when the pattern has an active deployment, and inactive otherwise. Inactive endpoints still capture events for testing through tap mode.
Get webhook request logs
GET /api/patterns/:id/webhook-logs
Return paginated webhook request logs for all endpoints associated with a pattern. Logs include accepted, rejected, rate-limited, and failed signature requests.
Authentication required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pattern ID |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by log status: accepted, signature_invalid, rate_limited, not_found, or inactive |
since | string (ISO 8601) | No | Return logs after this timestamp |
until | string (ISO 8601) | No | Return logs before this timestamp |
page | integer | No | Page number (default: 1) |
limit | integer | No | Items per page (default: 50, max: 100) |
Response
{
"logs": [
{
"id": "log_abc123",
"webhookId": "whk_abc123",
"patternId": "pat_abc123",
"status": "accepted",
"statusCode": 202,
"rejectionReason": null,
"ipAddress": "203.0.113.50",
"userAgent": "GitHub-Hookshot/abc1234",
"contentLength": 1024,
"requestId": "req_abc123",
"createdAt": "2026-03-05T11:45:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 50,
"total": 156,
"totalPages": 4
}
}Clear webhook request logs
DELETE /api/patterns/:id/webhook-logs
Delete all webhook request logs for a pattern.
Authentication required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pattern ID |
Response
{
"cleared": true
}Get tap events
GET /api/patterns/:id/tap-events
Return live-captured webhook payloads from the tap buffer. Tap mode captures the most recent 20 events per endpoint, regardless of deployment status. Events expire after 30 minutes.
Authentication required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pattern ID |
Response
{
"events": [
{
"nodeId": "node_1",
"webhookAlias": "github-events",
"receivedAt": "2026-03-05T11:45:00.000Z",
"eventData": {
"headers": {
"content-type": "application/json",
"x-github-event": "push"
},
"body": {
"action": "opened",
"repository": "my-org/my-repo"
},
"method": "POST",
"query": {}
}
}
]
}Clear tap events
DELETE /api/patterns/:id/tap-events
Clear the tap buffer for all webhook endpoints associated with a pattern.
Authentication required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pattern ID |
Response
{
"cleared": true
}Workspace webhook logs
GET /api/triggers/webhook-logs
Return paginated webhook request logs across all of the authenticated user's deployments and patterns. This provides a workspace-level view of all webhook activity.
Authentication required.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by log status |
since | string (ISO 8601) | No | Return logs after this timestamp |
until | string (ISO 8601) | No | Return logs before this timestamp |
page | integer | No | Page number (default: 1) |
limit | integer | No | Items per page (default: 50, max: 100) |
Response
{
"logs": [
{
"id": "log_abc123",
"webhookId": "whk_abc123",
"patternId": "pat_abc123",
"status": "accepted",
"statusCode": 202,
"ipAddress": "203.0.113.50",
"userAgent": "GitHub-Hookshot/abc1234",
"createdAt": "2026-03-05T11:45:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 50,
"total": 312,
"totalPages": 7
}
}Clear workspace webhook logs
DELETE /api/triggers/webhook-logs
Delete all webhook request logs across the authenticated user's patterns.
Authentication required.
Response
{
"cleared": true
}