> ## Documentation Index
> Fetch the complete documentation index at: https://cerebrium-fix-make-entrypoint-docs-explicit.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Forwarding

> Forward responses to a specified webhook

An HTTP request to the Cerebrium API can be parameterized to forward data from your function/app to a specified endpoint via a POST.
This allows you to use webhooks in your architecture. To achieve this, we can simply add the `webhookEndpoint`
query parameter to any API call:

```bash theme={null}
curl -X POST https://api.aws.us-east-1.cerebrium.ai/v4/<YOUR-PROJECT-ID>/<YOUR-APP>/run?webhookEndpoint=https%3A%2F%2Fwebhook.site%2F'\
       -H 'Content-Type: application/json'\
       -H 'Authorization: Bearer <YOUR-JWT-TOKEN>\
       --data '{"param": "hello world"}'
```

This will then forward the body by sending a POST request to your specified webhook. Since this is
a feature of our proxy, you will not need to modify any part of your code to use the webhook
functionality. You should, however, ensure that your endpoint is able to receive POST requests. While
this will work for both cortex and Custom runtimes, it will only work for HTTP requests, and not websockets.

## Retry Behavior

Webhook requests are sent asynchronously and will not block your function's response. If a webhook delivery fails,
we automatically retry with the following behavior:

* **Maximum attempts**: 3 attempts total
* **Delay between retries**: Up to 5 seconds between attempts

**Retry conditions:**

* Network errors (connection failures, timeouts) will trigger retries
* `404 Not Found` responses will trigger retries (endpoint may be temporarily unreachable)
* Other `4xx` client errors will **not** be retried (considered permanent failures)
* `5xx` server errors will **not** be retried (to avoid potential duplicate side effects)
* Non-2xx responses (excluding the above) will trigger retries

If all attempts fail, the error is logged but will not affect your function's response to the original caller.

<Warning>
  **Your webhook endpoint should be idempotent.** In some cases, we may retry a
  webhook even if it was processed successfully—for example, if our backend
  doesn't receive the success response from your webhook server due to network
  issues. Design your endpoint to handle duplicate deliveries gracefully.
</Warning>

To illustrate this, suppose your function returns `{"smile": "wave"}`. We would then make a POST call from
our proxy that would look like this to your webhook:

<Note>
  We do not actually use `curl`. This is used as an example to show what a
  webhook may expect.
</Note>

```bash theme={null}
curl -X POST https://webhook.site/'\
       -H 'Content-Type: application/json'\
       --data '{"smile": "wave"}'
```

## Webhook Signature Verification

To verify that webhooks are genuinely coming from Cerebrium, you can use our webhook signature verification system:

1. Include an `X-Webhook-Secret` header with a secret value of your choice when making requests to our API
2. When you receive a webhook, we'll include the following headers:

* `X-Request-Id`: A unique identifier for the request
* `X-Cerebrium-Webhook-Timestamp`: The Unix timestamp when the webhook was sent
* `X-Cerebrium-Webhook-Signature`: The signature in the format `v1,<signature>`

3. To verify the signature:

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

def verify_webhook_signature(request_id, timestamp, body, signature, secret):
    # Remove the 'v1,' prefix from the signature
    signature = signature.split(',')[1] if ',' in signature else signature

    # Construct the signed content
    signed_content = f"{request_id}.{timestamp}.{body}"

    # Calculate expected signature
    expected_signature = hmac.new(
        secret.encode(),
        signed_content.encode(),
        hashlib.sha256
    ).hexdigest()

    # Compare signatures
    return hmac.compare_digest(expected_signature, signature)
```

<Note>
  The body should include everything returned from cerebrium (run\_id, function
  response, timestamp etc) not just your function response
</Note>

This ensures that the webhook is genuinely from Cerebrium and hasn't been tampered with.
