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

# Rotate Webhook Signing Key

> Generate a new API key for webhook signature verification

# Rotate Webhook Signing Key

POST [https://api.baanx.com/v1/webhooks/\{id}/rotate-key](https://api.baanx.com/v1/webhooks/\{id}/rotate-key)
Generates a new API key for webhook signature verification and immediately invalidates the old one.

## Overview

Use this endpoint when you need to rotate your webhook signing key — for example, if the key has been compromised or as part of a routine key rotation policy.

<Warning>
  **Immediate invalidation.** The old API key is invalidated the moment this endpoint is called. Any in-flight webhooks that were signed with the old key will fail signature verification on your end.

  **Save the new key immediately.** The full API key is returned only once and cannot be retrieved again.
</Warning>

## Authentication

This endpoint requires authentication via Bearer token:

```bash theme={null} theme={null}
Authorization: Bearer YOUR_ACCESS_TOKEN
```

## Request

### Headers

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication
</ParamField>

### Path Parameters

<ParamField path="id" type="string (UUID)" required>
  Unique identifier of the webhook configuration
</ParamField>

### Request Example

<CodeGroup>
  ```bash cURL theme={null} theme={null}
  curl -X POST https://api.baanx.com/v1/webhooks/550e8400-e29b-41d4-a716-446655440000/rotate-key \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={null} theme={null}
  const webhookId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(
    `https://api.baanx.com/v1/webhooks/${webhookId}/rotate-key`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
      }
    }
  );

  const data = await response.json();
  // ⚠️ Store data.data.apiKey securely - it won't be shown again
  console.log(data);
  ```

  ```python Python theme={null} theme={null}
  import requests

  webhook_id = "550e8400-e29b-41d4-a716-446655440000"
  url = f"https://api.baanx.com/v1/webhooks/{webhook_id}/rotate-key"
  headers = {
      "Authorization": "Bearer YOUR_ACCESS_TOKEN"
  }

  response = requests.post(url, headers=headers)
  data = response.json()
  # ⚠️ Store data["data"]["apiKey"] securely - it won't be shown again
  print(data)
  ```

  ```typescript TypeScript theme={null} theme={null}
  const rotateWebhookKey = async (webhookId: string) => {
    const response = await fetch(
      `https://api.baanx.com/v1/webhooks/${webhookId}/rotate-key`,
      {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    // ⚠️ Store result.data.apiKey securely - it won't be shown again
    return result;
  };
  ```
</CodeGroup>

## Response

### 200 Success

<Warning>
  Store the `apiKey` from the response immediately and securely. It will **not** be shown again.
</Warning>

<ResponseField name="success" type="boolean">
  Indicates the key was rotated successfully
</ResponseField>

<ResponseField name="data.apiKey" type="string">
  **New full API key** — store securely and update your webhook receiver immediately. The old key is now invalid.
</ResponseField>

<ResponseField name="data" type="object">
  Full webhook configuration. See [Get Webhook](/api-reference/webhooks/get-webhook) for all field descriptions.
</ResponseField>

<ResponseExample>
  ```json 200 - Success theme={null} theme={null}
  {
    "success": true,
    "data": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "tenant": "partner-name",
      "name": "KYC Status Webhook",
      "url": "https://api.partner.com/webhooks/kyc",
      "apiKey": "whk_z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0f9e8d7c6b5a4z3y2x1w0v9u8",
      "eventTypes": ["kyc.status.changed"],
      "isActive": true,
      "metadata": {},
      "createdAt": "2025-12-29T10:00:00.000Z",
      "updatedAt": "2025-12-29T14:00:00.000Z"
    }
  }
  ```
</ResponseExample>

## Error Responses

<ResponseExample>
  ```json 401 - Unauthorized theme={null} theme={null}
  {
    "message": "Not authenticated"
  }
  ```

  ```json 403 - Forbidden theme={null} theme={null}
  {
    "message": "Not authorized"
  }
  ```

  ```json 404 - Not Found theme={null} theme={null}
  {
    "message": "Webhook config not found"
  }
  ```

  ```json 503 - Service Unavailable theme={null} theme={null}
  {
    "message": "Notification service is not configured for this environment"
  }
  ```
</ResponseExample>

## Key Rotation Checklist

<AccordionGroup>
  <Accordion title="Before Rotating">
    1. Ensure you have a secure place to store the new key (e.g., a secrets manager)
    2. Notify your team that a rotation is occurring
    3. Be prepared to update your webhook receiver immediately after rotation
  </Accordion>

  <Accordion title="After Rotating">
    1. **Immediately** store the new `apiKey` from the response in your secrets manager
    2. Deploy the new key to your webhook receiver
    3. Verify incoming webhooks are being verified correctly with the new key
    4. Monitor your [delivery logs](/api-reference/webhooks/webhook-logs) for any signature failures
  </Accordion>
</AccordionGroup>

## Related Endpoints

* `GET /v1/webhooks/{id}` - Get current webhook configuration
* `GET /v1/webhooks/{id}/logs` - Monitor delivery success after key rotation
* `POST /v1/webhooks` - Create a new webhook (also returns a full key)
