Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.trulayer.ai/llms.txt

Use this file to discover all available pages before exploring further.

TruLayer can POST a signed JSON payload to a URL you own whenever a monitored event fires — for example, when a failure is detected in your traces. This guide covers registration, signature verification, the test-ping endpoint, and URL validation rules. Webhooks are available on Pro plan and above. Creating and deleting webhooks requires the Member or Owner role.

Register a webhook

POST /v1/webhooks
Authorization: Bearer <api-key>
Content-Type: application/json
{
  "url": "https://your-app.example.com/hooks/trulayer",
  "secret": "at-least-16-chars-random-secret",
  "events": ["failure.detected"],
  "enabled": true
}
FieldTypeRequiredDescription
urlstring (URI)YesHTTPS endpoint TruLayer posts events to. Must satisfy the URL requirements below.
secretstringYesMinimum 16 characters. Used to compute the X-TruLayer-Signature header on every delivery.
eventsstring[]NoEvent types to subscribe to. Defaults to ["failure.detected"].
enabledbooleanNoWhether deliveries are active. Defaults to true.
A successful response is 201 Created with the new Webhook object.

URL requirements

TruLayer validates the URL at creation time. The request returns 422 if any of these checks fail:
Error keyMeaning
webhook.url.not_httpsThe URL scheme is not https. HTTP URLs are not accepted.
webhook.url.private_ipThe URL hostname resolves to a private, loopback, or link-local IP address. This protects against SSRF.
webhook.url.unresolvableThe URL hostname could not be resolved via DNS at registration time.
Example 422 response:
{
  "error": "webhook.url.not_https"
}

Verify a webhook before enabling it

Use POST /v1/webhooks/:id/test to send a synthetic ping event to your endpoint and inspect the response, without waiting for a real event to fire.
POST /v1/webhooks/018f1234-5678-7abc-def0-123456789abc/test
Authorization: Bearer <api-key>
No request body is required. Response 200 OK:
{
  "status": 204,
  "body": ""
}
FieldTypeDescription
statusintegerThe HTTP status code your endpoint returned. 0 means TruLayer could not reach the endpoint (DNS failure, refused connection, TLS error, or timeout).
bodystringThe first 4 KB of the response body your endpoint returned. Useful for debugging rejection messages.
The test delivery is signed with the same HMAC-SHA256 scheme used for live deliveries, so you can fully exercise your signature-verification logic. The delivery is ephemeral — it does not appear in the delivery log.

Auth and plan requirements

POST /v1/webhooks/:id/test requires:
  • Bearer token authentication (same as all other /v1/ endpoints)
  • Pro plan or above — Starter plan tenants receive 403
  • Member or Owner role — Viewer role receives 403

Error responses

StatusMeaning
404Webhook not found, or belongs to a different tenant
403Insufficient plan or role
422The webhook URL failed validation (see URL requirements)

Signature verification

Every delivery — live or synthetic — includes an X-TruLayer-Signature header. Verify it before processing the payload. The header value is sha256=<hex>, where the hex string is the HMAC-SHA256 of the raw request body using the secret you provided at registration time.
import hashlib
import hmac

def verify_signature(body: bytes, secret: str, header: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header)
Always use a timing-safe comparison to prevent timing attacks.

Event types

EventFired when
failure.detectedA failure is detected in your traces (matches a failure rule)
pingA synthetic test delivery via POST /v1/webhooks/:id/test

List and delete webhooks

List all webhooks for your tenant:
GET /v1/webhooks
Authorization: Bearer <api-key>
Delete a webhook (Owner role required):
DELETE /v1/webhooks/:id
Authorization: Bearer <api-key>