---
title: "Set Webhook Secret - API Reference"
description: "Set or rotate the shared secret used to sign SocialData webhook requests, so your server can verify their authenticity"
source: "https://docs.socialdata.tools/monitoring/set-webhook-secret/"
---

Sets the shared secret used to sign every webhook we send you. Your server uses the same value to confirm a request is authentic — see [Verifying webhooks](https://docs.socialdata.tools/monitoring/verifying-webhooks/) for how.

You choose the value; there is no generate-a-secret endpoint. Use a CSPRNG rather than inventing one by hand:

```bash
openssl rand -hex 32
```

Calling this endpoint again replaces the previous secret. The account has one secret, shared by every monitor and every webhook URL.

POST https://api.socialdata.tools/user/webhook/secret

## Headers

**Authorization** `string` — required

Authorization Bearer header containing your SocialData API key

Example: Bearer YOUR\_API\_KEY

## Body

**secret** `string` — required

The shared secret used to sign webhook requests. Maximum 256 characters. Store it somewhere your webhook handler can read it, and treat it like a password

Example: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

> **The secret cannot be read back**
> 
> There is no endpoint that returns your current secret — it can only be overwritten. If you lose it, set a new one and update your handler.

## Code Examples

#### curl

```shellscript
curl -X POST "https://api.socialdata.tools/user/webhook/secret" \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -d '{"secret": "YOUR_WEBHOOK_SECRET"}'
```

#### JavaScript

```js
const API_KEY = 'YOUR_API_KEY_HERE';
const webhookSecret = 'YOUR_WEBHOOK_SECRET';

fetch('https://api.socialdata.tools/user/webhook/secret', {
    method: 'POST',
    headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    },
    body: JSON.stringify({ secret: webhookSecret })
})
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
```

#### Python

```python
import requests

API_KEY = 'YOUR_API_KEY_HERE'
webhook_secret = 'YOUR_WEBHOOK_SECRET'

url = 'https://api.socialdata.tools/user/webhook/secret'

headers = {
    'Authorization': f'Bearer {API_KEY}',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}

payload = {'secret': webhook_secret}

response = requests.post(url, json=payload, headers=headers)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f"Error: {response.status_code}")
    print(response.text)
```

#### PHP

```php
$API_KEY = 'YOUR_API_KEY_HERE';
$webhook_secret = 'YOUR_WEBHOOK_SECRET';

$url = "https://api.socialdata.tools/user/webhook/secret";

$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode(['secret' => $webhook_secret]),
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $API_KEY",
        "Content-Type: application/json",
        "Accept: application/json"
    ]
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);

curl_close($ch);
```

## Example Responses

#### 200

```json
{
  "status": "success",
  "message": "Webhook secret updated"
}
```

#### 422

```json
{
  "message": "The secret field is required.",
  "errors": {
    "secret": [
      "The secret field is required."
    ]
  }
}
```

## Response Codes

-   **200 OK** - request succeeded
-   **422 Unprocessable Content** - validation failed (e.g. one of the required parameters was not provided)

## Rotating the secret

New deliveries are signed with the new value as soon as the change takes effect. Deliveries already in flight were signed with the old one, so a strict handler will reject them.

If dropped events matter, accept either secret for a few minutes:

1.  Deploy a handler that treats a request as valid if it verifies against the old secret **or** the new one.
2.  Call this endpoint with the new secret.
3.  Once traffic has settled, remove the old secret from the handler.

## Related endpoints

-   [Set webhook URL](https://docs.socialdata.tools/monitoring/set-global-webhook-url/)
-   [Verifying webhooks](https://docs.socialdata.tools/monitoring/verifying-webhooks/)
-   [Monitor event history](https://docs.socialdata.tools/monitoring/monitor-event-history/)

## Before you integrate

-   [Authentication](https://docs.socialdata.tools/getting-started/authentication/)
-   [Rate limits](https://docs.socialdata.tools/getting-started/rate-limits/)
-   [Errors](https://docs.socialdata.tools/getting-started/errors/)
-   [Monitoring API pricing](https://docs.socialdata.tools/monitoring/pricing/)
-   [Processing webhook events](https://docs.socialdata.tools/monitoring/processing-webhooks/)
