Skip to content

Webhooks

Webhooks allow your application to receive real-time notifications when events occur in your TRST project. Instead of polling our API for changes, we'll send HTTP POST requests to your configured endpoint whenever specific events happen.

Overview

When you create a webhook subscription, we'll send an HTTP POST request to your specified URL whenever a subscribed event occurs. Each webhook delivery includes:

  • JSON payload containing event data
  • HMAC signature for verification (SHA-256)

Quick Start

1. Create a Webhook Endpoint

First, create an endpoint in your application to receive webhooks:

javascript
// Express.js example
app.post("/webhooks/trst", express.raw({ type: "application/json" }), async (req, res) => {
	try {
		// Verify the signature (see Security Guide)
		verifyWebhookSignature(req, process.env.TRST_WEBHOOK_SECRET)

		// Parse the event
		const event = JSON.parse(req.body.toString())

		// Acknowledge receipt immediately
		res.status(200).send("OK")

		// Process the event asynchronously
		processWebhookEvent(event).catch(console.error)
	} catch (error) {
		console.error("Webhook verification failed:", error)
		res.status(401).send("Unauthorized")
	}
})

2. Create a Webhook Subscription

Use the web interface or RESTful API to create a webhook subscription:

bash
curl -X POST https://api.prod.trstinc.ca/v1/project/{project_id}/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/trst",
    "event_types": ["enrollment.completed", "demo.scan.success"],
    "enabled": true
  }'

Response:

json
{
	"id": "webhook_abc123",
	"url": "https://your-app.com/webhooks/trst",
	"secret": "whsec_a1b2c3d4e5f6...",
	"event_types": ["enrollment.completed", "demo.scan.success"],
	"enabled": true,
	"created_at": "2024-11-02T15:00:00Z"
}

Save Your Secret

The secret is only returned once during creation. Store it securely—you'll need it to verify webhook signatures.

3. Verify Webhook Signatures

Always verify signatures to ensure requests came from TRST:

javascript
const crypto = require("crypto")

function verifyWebhookSignature(request, webhookSecret) {
	const signatureHeader = request.headers["x-webhook-signature"]
	if (!signatureHeader || !signatureHeader.startsWith("sha256=")) {
		throw new Error("Missing or invalid signature header")
	}

	const receivedSignature = signatureHeader.substring(7)
	const rawBody = request.rawBody

	const hmac = crypto.createHmac("sha256", webhookSecret)
	hmac.update(rawBody)
	const expectedSignature = hmac.digest("hex")

	if (
		!crypto.timingSafeEqual(
			Buffer.from(receivedSignature, "hex"),
			Buffer.from(expectedSignature, "hex"),
		)
	) {
		throw new Error("Invalid webhook signature")
	}

	return true
}

See the Security Guide for detailed verification instructions.

4. Handle Events

Process events based on their type:

javascript
function processWebhookEvent(event) {
  // Check for duplicates using event_id
  const alreadyProcessed = await db.events.exists({
    eventId: event.event_id
  });

  if (alreadyProcessed) {
    console.log('Duplicate event, skipping:', event.event_id);
    return;
  }

  // Handle event by type
  switch (event.event_type) {
    case 'enrollment.completed':
      await handleEnrollmentCompleted(event.data);
      break;
    case 'demo.scan.success':
      await handleDemoScanSuccess(event.data);
      break;
    case 'webhook.test':
      console.log('Test webhook received');
      break;
    default:
      console.warn('Unknown event type:', event.event_type);
  }

  // Mark as processed
  await db.events.create({
    eventId: event.event_id,
    processedAt: new Date()
  });
}

Available Events

TRST supports the following event types:

Event TypeDescription
enrollment.completedMember completed biometric enrollment
demo.scan.successDemo device successfully identified a user
webhook.testManual webhook test via API

See the Event Reference for detailed payload schemas.

Webhook Headers

Each webhook request includes these headers:

HeaderDescriptionExample
Content-TypeAlways application/jsonapplication/json
X-Webhook-SignatureHMAC-SHA256 signaturesha256=a1b2c3...

Delivery Guarantees

Retry Behavior

If your endpoint doesn't respond with a 2XX status code, we'll automatically retry with exponential backoff for up to 14 days.

Success Criteria

A delivery is considered successful if your endpoint:

  • Responds with HTTP status code 200-299
  • Responds within 20 seconds

Idempotency

Your webhook endpoint should be idempotent because:

  • You may receive duplicate deliveries in rare cases
  • Use the event_id to deduplicate events

Limits and Quotas

LimitValue
Maximum webhooks per project25
Request timeout20 seconds
Retry periodUp to 14 days
URL requirementHTTPS only (no HTTP)

URL Requirements

  • Must use HTTPS (not HTTP)
  • Must not target private/internal networks (SSRF protection)
  • Localhost is blocked in production environments

Managing Webhooks

All webhook subscription management is done through the RESTful API:

OperationEndpointAPI Reference
Create webhookPOST /project/{project_id}/webhooksView →
List webhooksGET /project/{project_id}/webhooksView →
Get webhookGET /project/{project_id}/webhooks/{webhook_id}View →
Update webhookPATCH /project/{project_id}/webhooks/{webhook_id}View →
Delete webhookDELETE /project/{project_id}/webhooks/{webhook_id}View →
List webhook DeliveriesGET /project/{project_id}/webhooks/{webhook_id}/deliveriesView →
List Delivery AttemptsGET /project/{project_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/attemptsView →
Send Test webhookPOST /project/{project_id}/webhooks/{webhook_id}/testView →

Testing Your Webhook

Use the test endpoint to verify your integration:

bash
curl -X POST https://api.prod.trstinc.ca/v1/project/{project_id}/webhooks/{webhook_id}/test \
  -H "Authorization: Bearer YOUR_API_KEY"

This sends a webhook.test event to your endpoint. See the Testing Guide for more details.

Next Steps

Ready to implement webhooks?

Support

If you need help with webhooks:

  • Check the Testing Guide for debugging tips
  • Review delivery history in the API for detailed error information
  • Contact support with the delivery ID for specific delivery issues