Webhooks let external systems react to TigerTrust events in near real-time — for example, paging on-call when a certificate goes into expiring, kicking off a Terraform run when a new CA is registered, or forwarding attestation failures to a SIEM. Every delivery is HMAC-signed with a per-endpoint secret so recipients can verify authenticity. All endpoints are namespaced under /api/integrations/* and require authentication.

List webhook endpoints

GET /api/integrations/webhooks
page
integer
default:"1"
limit
integer
default:"50"
data[].id
integer
data[].name
string
data[].url
string
HTTPS URL that will receive POST deliveries.
data[].events
string[]
Event types this endpoint is subscribed to.
data[].secret
string
HMAC signing secret. Prefixed whsec_, 40 bytes of entropy.
data[].enabled
boolean
data[].lastDelivery
string (ISO 8601)
data[].successRate
integer
Rolling percentage (0–100).
data[].totalDeliveries
integer
data[].failedDeliveries
integer
The secret is returned on every read. Store it once at creation time and treat subsequent reads as informational. Rotating a secret requires deleting and recreating the endpoint.

Create a webhook endpoint

POST /api/integrations/webhooks
name
string
required
url
string
required
Must be an absolute HTTPS URL that responds within 30s with a 2xx status.
events
string[]
required
Non-empty list. See the event catalog below.
enabled
boolean
default:"true"
curl -X POST https://api.tigertrust.example.com/api/integrations/webhooks \
  -H "X-API-Key: ck_9f2a...7c4e" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "PagerDuty - expiring certs",
    "url": "https://events.pagerduty.com/integration/v2/enqueue",
    "events": ["certificate.expiring", "certificate.expired"],
    "enabled": true
  }'
{
  "data": {
    "id": 71,
    "workspaceId": "ws_2p9x8f4",
    "name": "PagerDuty - expiring certs",
    "url": "https://events.pagerduty.com/integration/v2/enqueue",
    "events": ["certificate.expiring", "certificate.expired"],
    "secret": "whsec_H9r2G8yTn3v1LqXpZ4fJ6mBc0aWdKe7sUo5iP1tV",
    "enabled": true,
    "successRate": 100,
    "totalDeliveries": 0,
    "failedDeliveries": 0,
    "createdAt": "2026-08-25T14:22:03.812Z"
  }
}

Test delivery

POST /api/integrations/webhooks/:webhookId/test Enqueues a synthetic webhook.test event to the endpoint. Returns the deliveryId so you can trace it in the delivery log.
webhookId
integer
required
{
  "data": {
    "success": true,
    "message": "Test webhook queued for delivery",
    "deliveryId": 15872
  }
}

Delivery log

GET /api/integrations/webhooks/deliveries
webhookId
integer
Filter to a specific endpoint.
page
integer
default:"1"
limit
integer
default:"50"
data[].id
integer
data[].webhookEndpointId
integer
data[].event
string
data[].payload
object
Exact JSON body that was (or will be) POSTed.
data[].status
string
pending, success, failed.
data[].statusCode
integer
HTTP status returned by the receiver.
data[].responseTime
integer
Milliseconds to first byte.
data[].error
string
Populated when status=failed.
data[].attempts
integer
Includes retries.
data[].createdAt
string (ISO 8601)

Delivery format

Each delivery is a POST to the configured url with:
Content-Type: application/json
User-Agent: TigerTrust-Webhooks/1.0
X-TigerTrust-Event: certificate.expiring
X-TigerTrust-Delivery: 15872
X-TigerTrust-Signature: t=1756131723,v1=<hex>
The signature uses HMAC-SHA256 over <timestamp>.<raw-body> with the endpoint’s secret as the key. Verifying in Node.js:
import crypto from "node:crypto";

function verify(rawBody, headerValue, secret) {
  const parts = Object.fromEntries(
    headerValue.split(",").map((p) => p.split("="))
  );
  const signed = `${parts.t}.${rawBody}`;
  const expected = crypto.createHmac("sha256", secret).update(signed).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}

Retries

Failed deliveries (non-2xx or timeout) are retried with exponential backoff — 30s, 2m, 10m, 1h, 6h — up to 5 attempts. The attempts counter on the delivery row tracks this; status flips to failed only after the final attempt.

Event catalog

Commonly-used event types (non-exhaustive):
EventFires when
certificate.createdA cert is imported or issued
certificate.updatedAny field mutation
certificate.expiringEnters the 30-day expiry window
certificate.expiredPasses expiresAt
certificate.revokedMarked revoked
certificate.renewedRenewal succeeds
ca.created / ca.updated / ca.health_changedCA lifecycle
discovery.scan_completedScan reaches terminal state
discovery.new_certificates_foundFresh unknown certs surface
workflow.execution_completedExecution terminates
attestation.failedAny attest-and-provision failure
webhook.testEmitted by the /test endpoint
Subscribe to ["*"] to receive everything.

External integrations

Adjacent to webhooks are external integrations — outbound connectors to Slack, Jira, ServiceNow, etc. These share the same URL surface:
  • GET /api/integrations/external — list configured integrations
  • POST /api/integrations/external — create with { name, type, configuration }
Integration type values include slack, msteams, pagerduty, jira, servicenow, splunk, datadog.

See also

  • Workflows — the primary source of automation events
  • Certificates — the resource most events describe
  • Authentication — creating the API key you’ll use to manage endpoints