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

# Server SDKs - Webhooks

> Use Authsignal's server SDKs to verify webhook requests.

## Verifying incoming requests

The Authsignal Server SDK can be used to parse and verify incoming [webhook events](/advanced-usage/webhooks/introduction).

<CodeGroup>
  ```ts Node.js theme={null}
  const authsignal = new Authsignal({ apiSecretKey: "YOUR_SERVER_API_SECRET_KEY" });

  // Obtain raw request body and signature header
  // For example using Express (https://expressjs.com/)
  const payload = req.body;
  const sig = req.headers["X-Signature-V2"];

  const event = authsignal.webhook.constructEvent(payload, sig);
  ```

  ```csharp C# theme={null}
  var authsignal = new AuthsignalClient("YOUR_SERVER_API_SECRET_KEY");

  // Obtain raw request body and signature header
  var payload = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
  var sig = Request.Headers["X-Signature-V2"];

  var webhookEvent = authsignal.Webhook.ConstructEvent(payload, sig);
  ```

  ```java Java theme={null}
  AuthsignalClient authsignal = new AuthsignalClient("YOUR_SERVER_API_SECRET_KEY");

  // Obtain raw request body and signature header
  // For example using the Spark framework (http://sparkjava.com)
  String payload = request.body();
  String sig = request.headers("X-Signature-V2");

  WebhookEvent event = authsignal.webhook.constructEvent(payload, sig);
  ```

  ```ruby Ruby theme={null}
  authsignal = Authsignal::Client.new(api_secret_key: 'YOUR_SERVER_API_SECRET_KEY')

  # Obtain raw request body and signature header
  payload = request.body.read
  sig = request.headers['X-Signature-V2']

  event = authsignal.webhook.construct_event(payload, sig)
  ```

  ```python Python theme={null}
  from authsignal import AuthsignalClient

  authsignal = AuthsignalClient(api_secret_key="YOUR_SERVER_API_SECRET_KEY")

  # Obtain raw request body and signature header
  payload = request.get_data(as_text=True)
  sig = request.headers.get("X-Signature-V2")

  event = authsignal.webhook.construct_event(payload, sig)
  ```

  ```PHP PHP theme={null}
  $authsignal = new Authsignal\Client('YOUR_SERVER_API_SECRET_KEY');

  // Obtain raw request body and signature header
  $payload = file_get_contents('php://input');
  $sig = $_SERVER['HTTP_X_SIGNATURE_V2'];

  $event = $authsignal->webhook()->constructEvent($payload, $sig);
  ```

  ```go Go theme={null}
  webhook := NewWebhook("YOUR_SERVER_API_SECRET_KEY")

  // Obtain raw request body and signature header
  payload := string(body)
  sig := r.Header.Get("X-Signature-V2")

  event, err := webhook.ConstructEventWithDefaultTolerance(payload, sig)
  ```
</CodeGroup>

<Warning>
  The Authsignal SDK requires the **raw body** of the request to verify the signature. If you’re
  using a framework, make sure it doesn’t manipulate the raw body as this will cause the signature
  verification to fail.
</Warning>

To prevent against replay attacks, the SDK will error if more than **5 minutes** has elapsed since the time that the event was sent.
This threshold can be customized by passing a `tolerance` value - the time (in minutes) after which requests should be rejected.

<CodeGroup>
  ```ts Node.js theme={null}
  const payload = req.body;
  const sig = req.headers["X-Signature-V2"];
  const tolerance = 10;

  const event = authsignal.webhook.constructEvent(payload, sig, tolerance);
  ```

  ```csharp C# theme={null}
  var payload = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
  var sig = Request.Headers["X-Signature-V2"];
  var tolerance = 10;

  var webhookEvent = authsignal.Webhook.ConstructEvent(payload, sig, tolerance);
  ```

  ```java Java theme={null}
  String payload = request.body();
  String sig = request.headers("X-Signature-V2");
  int tolerance = 10;

  WebhookEvent event = authsignal.webhook.constructEvent(payload, sig, tolerance);
  ```

  ```ruby Ruby theme={null}
  payload = request.body.read
  sig = request.headers['X-Signature-V2']
  tolerance = 10

  event = authsignal.webhook.construct_event(payload, sig, tolerance)
  ```

  ```python Python theme={null}
  payload = request.get_data(as_text=True)
  sig = request.headers.get("X-Signature-V2")
  tolerance = 10

  event = authsignal.webhook.construct_event(payload, sig, tolerance)
  ```

  ```PHP PHP theme={null}
  $payload = file_get_contents('php://input');
  $sig = $_SERVER['HTTP_X_SIGNATURE_V2'];
  $tolerance = 10;

  $event = $authsignal->webhook()->constructEvent($payload, $sig, $tolerance);
  ```

  ```go Go theme={null}
  payload := string(body)
  sig := r.Header.Get("X-Signature-V2")
  tolerance := 10

  event, err := webhook.ConstructEvent(payload, sig, tolerance)
  ```
</CodeGroup>
