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

# Rotate Hook Secret

> Replace the secret that signs the webhook deliveries of a hook

Replaces the hook's signing secret with a new random one and returns it. This response is the only place the new secret appears: hook reads carry `signed`, never the secret. Nothing goes on-chain.

<Warning>
  The previous secret stops at once, with no overlap. Every attempt sent after this call is signed with the new secret, including retries of deliveries queued before it. A receiver that rejects a signature with a `4xx` other than `408`, `425` or `429` fails that delivery for good. Switch the receiver to the new secret right away, or have it answer a retried status such as `503` while it switches.
</Warning>

[Create Hook](/endpoints/lending/create-hook) issues a secret to every hook it creates, but only an `inform` action sends deliveries, so the secret is used only there. A hook whose `signed` reads `false` holds no secret, and its deliveries carry no `x-webhook-signature`. Rotating issues it one, and every attempt from then on is signed. [Signed deliveries](/endpoints/lending/create-hook#signed-deliveries) describes how the signature is computed.

The request takes no body.

## Path Parameters

<ParamField path="marketId" type="string" required>The market's record ID, as `id` on [List Markets](/endpoints/lending/list-markets), not its contract address. See [Market IDs](/endpoints/lending/list-markets#market-ids).</ParamField>
<ParamField path="hookId" type="string" required>Hook ID.</ParamField>

## Response Fields

<ResponseField name="data" type="object">
  <Expandable>
    <ResponseField name="id" type="string">Hook ID.</ResponseField>
    <ResponseField name="webhookSecret" type="string">The new secret: 32 random bytes as 64 lowercase hex characters. The HMAC key is this string exactly as returned, not the bytes it encodes.</ResponseField>
    <ResponseField name="rotatedAt" type="string">Time of the rotation, which is also the hook's new `updatedAt`.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/hooks/{marketId}/{hookId}/rotate-secret" \
    -H "X-API-Key: trusset_your_key_here"
  ```

  ```typescript TypeScript theme={null}
  const res = await fetch(
    `https://api.trusset.org/lending-external-securities-v2/api/hooks/${marketId}/${hookId}/rotate-secret`,
    { method: 'POST', headers: { 'X-API-Key': 'trusset_your_key_here' } }
  );
  const { data } = await res.json();
  const webhookSecret: string = data.webhookSecret;
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "id": "hook_004",
      "webhookSecret": "7350b6c5815644ebd5ff51d3ef2d32f6fe700cfa210f14bba8699b199d6fc52e",
      "rotatedAt": "2026-10-10T09:30:00.000Z"
    },
    "error": null,
    "metadata": {
      "timestamp": "2026-10-10T09:30:00.000Z",
      "requestId": "550e8400-e29b-41d4-a716-446655440000",
      "instanceId": "inst_abc123"
    }
  }
  ```

  ```json Error - Not Found theme={null}
  {
    "success": false,
    "data": null,
    "error": {
      "code": "HOOK_NOT_FOUND",
      "message": "Hook not found"
    }
  }
  ```
</ResponseExample>

## Error Codes

| Code | HTTP | Cause |
| - | - | - |
| `MISSING_MARKET_ID` | `400` | `marketId` is longer than 100 characters |
| `MISSING_HOOK_ID` | `400` | `hookId` is longer than 100 characters |
| `MARKET_NOT_FOUND` | `404` | No market with this ID belongs to your instance |
| `HOOK_NOT_FOUND` | `404` | No hook with this ID exists on this market |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.