Webhooks API
The Webhooks API is the ingress endpoint that receives external event payloads and triggers rule execution. Unlike other API endpoints, webhooks do not use session authentication. Instead, they are secured with a per-rule webhook secret passed via header.
Base path: /api/webhooks
Endpoint
/api/webhooks/rules/:ruleIdReceive a webhook payload to trigger rule execution.
Parameters
| Parameter | Location | Type | Description |
|---|---|---|---|
ruleId | path | UUID | The ID of the rule to trigger |
Required headers
| Header | Description |
|---|---|
x-webhook-secret | The webhook secret assigned to this rule |
Content-Type | Must be application/json |
Request body
The body is a raw JSON payload. Its structure depends on the event source (GitHub, Slack, custom, etc.). TinyOps passes the entire payload to the rule for evaluation.
{
"event": "push",
"repository": "acme/api",
"branch": "main",
"author": "dev@acme.com",
"commits": [
{ "id": "abc123", "message": "fix: resolve timeout" }
]
}Idempotency
Include the X-Delivery-Id header with a unique identifier for each delivery. TinyOps uses this to deduplicate webhook deliveries. If the same delivery ID is received within a 5-minute window, the duplicate is acknowledged with a 200 response but not processed again.
X-Delivery-Id: d7e8f9a0-1234-5678-abcd-ef0123456789HMAC Verification
When HMAC is enabled on a rule, TinyOps computes an HMAC-SHA256 signature of the request body using the webhook secret and includes it in the response for verification.
To verify incoming webhooks on your end, compute the HMAC yourself:
import crypto from 'crypto';
function verifySignature(body, secret, signature) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(body))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}HMAC signing is optional and must be enabled per-rule via the Rules API. See POST /api/rules/:id/hmac.
Response Codes
| Status | Meaning |
|---|---|
| 200 | Webhook received and rule execution started |
| 200 | Duplicate delivery (already processed) |
| 401 | Missing or invalid x-webhook-secret header |
| 404 | Rule not found or not configured for webhooks |
| 422 | Invalid JSON payload |
| 429 | Rate limit exceeded |
Example cURL
curl -X POST https://api.tinyops.cc/api/webhooks/rules/your-rule-id \
-H "Content-Type: application/json" \
-H "x-webhook-secret: whsec_abc123..." \
-H "X-Delivery-Id: unique-id-here" \
-d '{"event":"push","repository":"acme/api"}'Never expose your webhook secret in client-side code or public repositories. Rotate secrets immediately if compromised via POST /api/rules/:id/rotate-secret.