NAV Navbar
Logo
HTTP JavaScript

Topics

Introduction

Teamtailor’s Company Webhooks allow you to receive real-time notifications when data changes in Teamtailor. This enables seamless integration with your existing systems without constantly polling the API.

Key Benefits

Use Cases

Company Webhooks are ideal for:

Setting Up Webhooks

Prerequisites

To use Company Webhooks, you need:

  1. The Webhooks feature enabled for your company
  2. Administrator permissions in Teamtailor
  3. An endpoint that can receive webhook notifications (HTTPS required)

Configuration Steps

  1. In Teamtailor dashboard, go to Settings > Integrations > Webhooks
  2. Click Add webhook and provide:
    • Label: A descriptive name (e.g., “CRM Integration”)
    • Webhook URL: Your HTTPS endpoint
    • Events: Select the events you want to subscribe to
  3. Save the automatically generated signature key for security verification
  4. Test the connection to ensure your endpoint is receiving events

You can create multiple webhook subscriptions with different event filters to organize your integrations efficiently.

Event Types

Company Webhooks use a consistent naming pattern for events:

resource_name.action

Where: * resource_name is the object type (candidate, job, etc.) * action is what occurred (create, update, destroy)

Common Events

Candidate Events

Job Events

Job Application Events

Webhook Payloads

When an event occurs, Teamtailor sends a JSON payload to your endpoint containing details about the event.

Payload Structure

{
  "payload": {
    "event_name": "job.update",
    "data": {
      "id": "2",
      "type": "jobs",
      "attributes": {
        "title": "IT Designer 1",
        "body": "<p>Job description...</p>",
        "company-name": "Teamtailor",
        "cover-letter-requirement": "cover_letter_optional",
        "created-at": "2023-02-08T10:10:13.611+01:00",
        "employment-level": "none",
        "employment-type": "none",
        "human-status": "archived",
        "internal": false,
        "remote-status": "none",
        "status": "archived",
        "tags": [],
        "updated-at": "2023-02-22T22:10:48.705+01:00"
      }
    }
  },
  "signature": "YzU1N2FhOTUwMjlkNTFiMGM5NjIxNTEyODc5NGY5ZjgxZWNkMmNkZTZhNmIxYmI2YmM3NmVmYmQ1ZGZiMDg0Zg=="
}

The standard payload structure includes:

  1. payload: Object containing:
    • event_name: The type of event (e.g., “job.update”)
    • data: Resource data with:
      • id: Resource identifier
      • type: Resource type (e.g., “jobs”, “candidates”)
      • attributes: Resource-specific attributes
  2. signature: Base64-encoded signature for verification

For destroy events, the data structure is simpler but follows the same overall structure.

Resource-Specific Attributes

Each resource type includes different attributes in the payload:

Candidate

Job

Job Application

Headers

Each webhook request includes these headers:

Authentication & Security

Teamtailor uses multiple security measures to ensure webhook deliveries are secure and authentic.

Webhook Security

Each webhook request includes:

  1. A TT-Signature header containing the signature
  2. The same signature in the request body
  3. Optional authorization headers for partner-specific webhooks

This allows you to verify that the webhook is legitimately from Teamtailor.

HTTPS Requirements

All webhook endpoints must use HTTPS to ensure data is encrypted in transit. Teamtailor will not send webhooks to non-HTTPS URLs.

Authentication Headers

Based on the implementation in tt-webhooks, the following headers may be present:

const headers = {
  "TT-Signature": signature,
};

if (providerKey) {
  headers.authorization = `Bearer ${providerKey}`;
}

if (apiKey) {
  headers["teamtailor-api-token"] = apiKey;
}

The standard header for signature verification is TT-Signature.

Retry Mechanism

If your endpoint is temporarily unavailable or returns a non-2xx status code, Teamtailor will retry the webhook delivery:

After multiple failed attempts, if the webhook still fails to deliver, it will be logged as a failed delivery.

Webhook Signatures

To validate the authenticity of webhooks sent by Teamtailor, each request includes a TT-Signature header and a signature field in the payload. This allows you to verify the webhook came from Teamtailor.

Signature Format

The signature is a Base64-encoded hexadecimal string. In the example payload:

"signature": "YzU1N2FhOTUwMjlkNTFiMGM5NjIxNTEyODc5NGY5ZjgxZWNkMmNkZTZhNmIxYmI2YmM3NmVmYmQ1ZGZiMDg0Zg=="

Signature Verification

Based on the code in the tt-webhooks repository, the signature verification should follow this pattern:

const crypto = require('crypto');

// Get this from your webhook setup in Teamtailor
const SECRET_KEY = 'your_webhook_signature_key';

function verifyWebhookSignature(requestBody, signatureHeader) {
  const { payload } = requestBody;

  // Calculate expected signature
  // The exact calculation method may vary - check with Teamtailor for the exact formula
  const hmac = crypto.createHmac('sha256', SECRET_KEY)
    .update(payload.data.id.toString())
    .digest('hex');

  const expectedSignature = Buffer.from(hmac).toString('base64');

  // Compare signatures
  return signatureHeader === expectedSignature;
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['tt-signature'];

  if (!verifyWebhookSignature(req.body, signature)) {
    return res.status(401).send('Invalid signature');
  }

  // Process the webhook...
  res.status(200).send('Webhook processed');
});

Example Implementation (PHP)

<?php
// Get this from your webhook setup in Teamtailor
$secretKey = 'your_webhook_signature_key';

function verifySignature($requestBody, $signatureHeader, $secretKey) {
    $id = $requestBody['payload']['data']['id'];

    // Calculate the HMAC using SHA-256
    $hmac = hash_hmac('sha256', $id, $secretKey, true);

    // Convert to base64
    $expectedSignature = base64_encode(bin2hex($hmac));

    return hash_equals($signatureHeader, $expectedSignature);
}

// Webhook handler
$requestBody = json_decode(file_get_contents('php://input'), true);
$signature = $_SERVER['HTTP_TT_SIGNATURE'];

if (!verifySignature($requestBody, $signature, $secretKey)) {
    http_response_code(401);
    echo 'Invalid signature';
    exit;
}

// Process the webhook...
http_response_code(200);
echo 'Webhook processed';

Best Practices

Follow these best practices to ensure reliable and secure webhook integration with Teamtailor.

Implementation Recommendations

Webhook Processing

  1. Verify signatures - Always verify the signature before processing webhooks
  2. Process asynchronously - Handle webhooks asynchronously to respond quickly
  3. Idempotency - Design your webhook handlers to be idempotent (can safely receive the same webhook multiple times)
  4. Return quickly - Respond with a 200 status code as soon as possible, then process the webhook

Error Handling

  1. Graceful failures - Handle errors gracefully and log issues for debugging
  2. Webhook monitoring - Monitor webhook deliveries and failures
  3. Handle retries - Be prepared for webhooks to be retried if your endpoint is temporarily unavailable

Performance Considerations

  1. Selective subscriptions - Only subscribe to the events you need
  2. Efficient processing - Process webhooks efficiently to avoid bottlenecks
  3. Scalable infrastructure - Ensure your webhook endpoint can handle bursts of traffic

Security Guidelines

  1. HTTPS only - Always use HTTPS for webhook endpoints
  2. Signature verification - Always verify webhook signatures
  3. Secrets management - Securely store your webhook signature key
  4. Input validation - Validate webhook payloads before processing

Handling Duplicate Events

Webhooks might be delivered multiple times, especially during retries: - Use a unique identifier (like the event ID) to detect duplicates - Make your webhook processing idempotent