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

# Webhook

> Webhooks provide instant notifications when your phone calls are completed.

## Set Up the Webhook

Provide the `Webhook URL` where you want Volubile to send notifications in the [Webhook Integration Settings](https://eu.volubile.ai/integrations/webhooks).

## Webhook Payload

Once a call is completed or failed, a `POST` request will be sent to your `Webhook URL` with the details of the call. This is identical to the endpoint [*Get a call*](/api-reference/calls/get).

```json theme={null}
{
   "id":"3c90c3cc-0d44-4b50-8888-8dd25736052a",
   "agentId":"3c90c3cc-0d44-4b50-8888-8dd25736052a",
   "phone":"+33612345678",
   "type":"INBOUND",
   "duration":360,
   "startTime":"2024-07-30T14:35:00Z",
   "endTime":"2024-07-30T14:41:00Z",
   "anonymous":false,
   "status":"COMPLETED",
   "extractors":[
      {
         "name":"customer",
         "value":[
            {
               "name":"firstname",
               "value":[
                  "John"
               ]
            },
            {
               "name":"lastname",
               "value":[
                  "Doe"
               ]
            },
            {
               "name":"address",
               "value":[
                  "123 Main St"
               ]
            }
         ]
      },
      {
         "name":"example",
         "value":[
            "example1",
            "example2"
         ]
      }
   ],
   "extractedData":{
      "customer":{
         "firstname":"John",
         "lastname":"Doe",
         "address":"123 Main St"
      },
      "example":"example1"
   },
   "classifiers":[
      {
         "name":"Customer's request",
         "value":"Refund"
      },
      {
         "name":"Sentiment",
         "value":"Positive"
      }
   ],
   "classificationData":{
      "Customer's request":"Refund",
      "Sentiment":"Positive"
   },
   "context":{
      "firstName":"firstname",
      "lastName":"lastname",
      "commandNumber":"5HZ99FRT",
      "system.phone":"+33612345678"
   },
   "recorded":true,
   "summary":"Discussed project requirements and next steps.",
   "created":"2024-07-30T14:45:00Z"
}
```

## Secure the Webhook

You can choose to enable security for webhooks by generating a secret in the [Webhook Integration Settings](https://eu.volubile.ai/integrations/webhooks).

When enabled, we will include an `X-Webhook-Signature` in the request headers to your `Webhook URL`, allowing you to verify that the payload comes from Volubile.

Here is an example code demonstrating how to verify the `HMAC signature`:

<CodeGroup>
  ```java Java theme={null}
  import org.apache.commons.codec.binary.Hex;
  import java.security.InvalidKeyException;
  import java.security.NoSuchAlgorithmException;
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;
  import static java.nio.charset.StandardCharsets.UTF_8;
  ...

  final var SECRET_KEY = "{volubile - webhook - secret}";

  final var payload = """
  {
      "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
      "agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
      "type": "INBOUND",
      ...
  }
  """;

  try {
  final var mac = Mac.getInstance("HmacSHA256");
  mac.init(new SecretKeySpec(SECRET_KEY.getBytes(UTF_8), "HmacSHA256"));
  final byte[] rawHmac = mac.doFinal(payload.getBytes());
  final byte[] hexBytes = new Hex().encode(rawHmac);

  final var signature = new String(hexBytes, UTF_8);
  ...
  } catch (final NoSuchAlgorithmException | InvalidKeyException e) {
  logger.error("Error occurred!");
  }
  ```

  ```typescript TypeScript theme={null}
  const crypto = require("crypto");

  const SECRET_KEY = "{volubile - webhook - secret}";

  const payload = JSON.stringify({
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "type": "INBOUND",
  ...
  });

  const signature = crypto
  .createHmac("sha256", SECRET_KEY)
  .update(payload, "utf-8")
  .digest("hex");

  ...
  ```
</CodeGroup>

## Webhook retries

In case of 50x errors (500 error code and above) on your webhook endpoint we will retry up to 4 times, each time with an incremental delay of 1 second to not overload your servers.
