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

# Webhooks

> Subscribe to real-time platform events, verify signatures, replay failed deliveries, and manage subscriptions.

<Steps>
  <Step title="Create a Subscription">
    Point the platform at your endpoint and specify which events to receive. Save the `secret` — it's shown only once and is used to verify signatures on incoming requests.

    | Event                 | Triggered when                             |
    | --------------------- | ------------------------------------------ |
    | `deal.status_changed` | A deal moves to a new status               |
    | `loan.approved`       | A loan deal is approved for securitization |
    | `loan.rejected`       | A loan deal is rejected                    |
    | `trade.settled`       | An investor trade reaches settlement       |
    | `sc.completed`        | A Selection Criteria job finishes          |
    | `document.uploaded`   | A document is uploaded to the deal room    |

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.9squid.com/v1/api/webhooks/subscriptions \
        -H "Authorization: Bearer <your_token>" \
        -H "Content-Type: application/json" \
        -d '{
          "url": "https://your-server.com/webhooks/9squid",
          "events": ["deal.status_changed", "loan.approved", "trade.settled"]
        }'
      ```

      ```json Response theme={null}
      {
        "success": true,
        "data": {
          "id": "clxsub001",
          "url": "https://your-server.com/webhooks/9squid",
          "events": ["deal.status_changed", "loan.approved", "trade.settled"],
          "secret": "whsec_abc123xyz",
          "created_at": "2026-04-15T10:00:00Z"
        }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="View Delivery History">
    Check which events have been delivered and whether they succeeded.

    <CodeGroup>
      ```bash cURL theme={null}
      curl https://api.9squid.com/v1/api/webhooks/deliveries \
        -H "Authorization: Bearer <your_token>"
      ```

      ```json Response theme={null}
      {
        "success": true,
        "data": [
          {
            "id": "clxdlv001",
            "event": "deal.status_changed",
            "status": "DELIVERED",
            "http_status": 200,
            "attempts": 1,
            "created_at": "2026-04-15T11:00:00Z"
          },
          {
            "id": "clxdlv002",
            "event": "loan.approved",
            "status": "FAILED",
            "http_status": 503,
            "attempts": 3,
            "created_at": "2026-04-15T11:05:00Z"
          }
        ]
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Replay a Failed Delivery">
    If your server was down or returned a non-2xx, trigger a replay.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.9squid.com/v1/api/webhooks/deliveries/clxdlv002/replay \
        -H "Authorization: Bearer <your_token>"
      ```

      ```json Response theme={null}
      {
        "success": true,
        "data": {
          "delivery_id": "clxdlv003",
          "status": "PENDING"
        }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Verify Webhook Signatures">
    Every delivery includes an `X-9Squid-Signature` header. Verify it using the `secret` from Step 1.

    Always reject requests where the signature does not match.

    <CodeGroup>
      ```bash cURL theme={null}
      const crypto = require('crypto');

      function verifyWebhook(payload, signature, secret) {
        const expected = crypto
          .createHmac('sha256', secret)
          .update(payload)
          .digest('hex');
        return crypto.timingSafeEqual(
          Buffer.from(signature),
          Buffer.from(`sha256=${expected}`)
        );
      }
      ```

      ```json Webhook Payload Shape theme={null}
      {
        "event": "deal.status_changed",
        "timestamp": "2026-04-15T11:00:00Z",
        "data": {
          "deal_id": "clx1a2b3c4d5e6f7g8h9",
          "previous_status": "IN_REVIEW",
          "current_status": "QC_COMPLETED"
        }
      }
      ```
    </CodeGroup>
  </Step>
</Steps>
