> ## Documentation Index
> Fetch the complete documentation index at: https://partner-docs.fastgen.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Learn how to integrate and manage webhooks in Fastgen

# Webhook System

Fastgen's webhook system enables real-time integration between your applications and our platform. This event-driven approach allows you to build automated workflows and maintain data synchronization across your entire technology stack.

## Why Use Webhooks?

Modern applications require efficient communication and data sharing mechanisms. Webhooks provide several advantages:

<CardGroup>
  <Card title="Real-time Updates" icon="bolt">
    Receive instant notifications instead of constantly polling for changes
  </Card>

  <Card title="Automated Workflows" icon="gears">
    Create seamless automation between different systems and services
  </Card>

  <Card title="Efficient Resources" icon="gauge-high">
    Reduce system load and latency compared to traditional polling methods
  </Card>

  <Card title="Easy Integration" icon="puzzle-piece">
    Connect with your existing tools and services with minimal setup
  </Card>
</CardGroup>

## Configuration

### Setting Up Webhooks

Configure your webhook endpoints through our dashboard:

[https://app.fastgen.ai/webhooks](https://app.fastgen.ai/webhooks)

You can set up multiple webhook URLs to receive different types of events, allowing for flexible event routing based on your needs.

<Tip>
  Consider setting up separate webhooks for development and production environments to streamline your testing process.
</Tip>

### Security

We implement HMAC Webhook Integrity Protection to ensure secure communication:

<Steps>
  <Step title="Signature Generation">
    Each webhook request includes a unique signature created using SHA-256 hashing and a shared secret key
  </Step>

  <Step title="Verification">
    Your server should verify this signature before processing any webhook data to ensure authenticity
  </Step>

  <Step title="Secret Management">
    Access your Signature Secret in the webhook configuration section at app.fastgen.ai/webhooks
  </Step>
</Steps>

<Warning>
  Never share your Signature Secret or commit it to version control. Always use secure environment variables to store sensitive information.
</Warning>

### Monitoring

Track all webhook activities through our logging system:

[https://app.fastgen.ai/logs](https://app.fastgen.ai/logs)

The logging interface provides visibility into:

* Incoming webhook requests
* Outgoing webhook deliveries
* Delivery status and debugging filters

## Best Practices

<AccordionGroup>
  <Accordion title="Implement Signature Verification">
    Always verify webhook signatures on your receiving endpoint to ensure security
  </Accordion>

  <Accordion title="Handle Errors Properly">
    Implement proper error handling and retry mechanisms for failed webhook deliveries
  </Accordion>

  <Accordion title="Monitor Regularly">
    Keep track of webhook logs to ensure smooth operation and quickly identify issues
  </Accordion>

  <Accordion title="Configure Timeouts">
    Set appropriate timeout settings based on your processing requirements
  </Accordion>

  <Accordion title="Handle High Volume">
    Implement proper queue handling for processing high-volume webhook requests
  </Accordion>
</AccordionGroup>

## Getting Started

Follow these steps to begin using webhooks:

<Steps>
  <Step title="Configure Endpoint">
    Navigate to the webhook configuration page and add your endpoint URL
  </Step>

  <Step title="Get Secret">
    Copy your signature secret from the webhook settings
  </Step>

  <Step title="Implement Verification">
    Add signature verification to your application using our example code
  </Step>

  <Step title="Test Integration">
    Use our testing tools to verify your webhook setup
  </Step>

  <Step title="Monitor">
    Check the logs to ensure proper functionality
  </Step>
</Steps>

## Webhook Message Format

### Initial Response

When sending a request to a workflow API route, you'll receive a webhook message ID:

```json theme={null}
{
    "webhook_message_id": "9bde801d-bb41-417b-aaa6-50f7438085aa"
}
```

### Webhook Payload

The webhook request to your configured endpoint will include:

```json theme={null}
{
    "event": "cv-score-finished",
    "id": "9bde801d-bb41-417b-aaa6-50f7438085aa",
    "payload": {
        ...
    }
}
```

Key components of the webhook payload:

* `event`: The type of event that triggered the webhook
* `id`: The webhook message ID (matches the initially returned ID)
* `payload`: The actual data containing the event details

### Headers

The webhook request includes a signature header for verification:

```
X-Fastgen-Signature: 854d567aea3fdeedbd58b827938d0d793be15a7ec0d23b7d8a175578724d34bd
```

<Tip>
  Always verify the webhook signature using the `X-Fastgen-Signature` header before processing the webhook data.
</Tip>

## Code Examples

Here's how to verify webhook signatures in different languages:

<CodeGroup>
  ```javascript Node.js theme={null}
  const crypto = require('crypto');

  function verifyWebhookSignature(payload, signature, secret) {
    const hmac = crypto.createHmac('sha256', secret);
    const digest = hmac.update(payload).digest('hex');
    return crypto.timingSafeEqual(
      Buffer.from(signature),
      Buffer.from(digest)
    );
  }
  ```

  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_webhook_signature(payload, signature, secret):
      computed_signature = hmac.new(
          secret.encode('utf-8'),
          payload.encode('utf-8'),
          hashlib.sha256
      ).hexdigest()
      return hmac.compare_digest(signature, computed_signature)
  ```

  ```php PHP theme={null}
  <?php
  function verifyWebhookSignature($payload, $signature, $secret) {
      $computedSignature = hash_hmac('sha256', $payload, $secret);
      return hash_equals($signature, $computedSignature);
  }
  ```

  ```go Go theme={null}
  package main

  import (
      "crypto/hmac"
      "crypto/sha256"
      "crypto/subtle"
      "encoding/hex"
  )

  func verifyWebhookSignature(payload []byte, signature, secret string) bool {
      mac := hmac.New(sha256.New, []byte(secret))
      mac.Write(payload)
      expectedMAC := hex.EncodeToString(mac.Sum(nil))
      
      return subtle.ConstantTimeCompare([]byte(signature), []byte(expectedMAC)) == 1
  }
  ```

  ```java Java theme={null}
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;
  import java.nio.charset.StandardCharsets;
  import java.security.InvalidKeyException;
  import java.security.NoSuchAlgorithmException;

  public class WebhookVerifier {
      public static boolean verifySignature(String payload, String signature, String secret) 
              throws NoSuchAlgorithmException, InvalidKeyException {
          Mac sha256Hmac = Mac.getInstance("HmacSHA256");
          SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
          sha256Hmac.init(secretKey);
          
          byte[] computedHash = sha256Hmac.doFinal(payload.getBytes(StandardCharsets.UTF_8));
          String computedSignature = bytesToHex(computedHash);
          
          return constantTimeEquals(signature, computedSignature);
      }
      
      private static String bytesToHex(byte[] hash) {
          StringBuilder hexString = new StringBuilder();
          for (byte b : hash) {
              String hex = Integer.toHexString(0xff & b);
              if (hex.length() == 1) hexString.append('0');
              hexString.append(hex);
          }
          return hexString.toString();
      }
      
      private static boolean constantTimeEquals(String a, String b) {
          byte[] bytes1 = a.getBytes(StandardCharsets.UTF_8);
          byte[] bytes2 = b.getBytes(StandardCharsets.UTF_8);
          return bytes1.length == bytes2.length && 
                 MessageDigest.isEqual(bytes1, bytes2);
      }
  }
  ```
</CodeGroup>

<Tip>
  Remember to handle the raw request body when verifying signatures, as parsed bodies might have slightly different formats.
</Tip>
