> For the complete documentation index, see [llms.txt](https://docs.bv7x.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bv7x.ai/use-the-signal/read-the-forecast/webhooks.md).

# Webhooks

Register a URL to receive signal events via HTTP POST. The server pushes events to your endpoint as they happen.

***

## Register a Webhook

```
POST /api/bv7x/webhooks/register
Authorization: Bearer <token>
Content-Type: application/json
```

**Authentication**: Basic tier (500M+ $BV7X)

### Request

```json
{
  "url": "https://your-server.com/bv7x-webhook",
  "events": ["signal.new", "signal.resolved", "wager.placed"],
  "secret": "your-webhook-secret"
}
```

| Field    | Type   | Required | Description                                    |
| -------- | ------ | -------- | ---------------------------------------------- |
| `url`    | string | Yes      | HTTPS endpoint that will receive POST requests |
| `events` | array  | Yes      | Event types to subscribe to                    |
| `secret` | string | Yes      | Shared secret for HMAC signature verification  |

### Response

```json
{
  "id": "wh_abc123",
  "url": "https://your-server.com/bv7x-webhook",
  "events": ["signal.new", "signal.resolved", "wager.placed"],
  "active": true,
  "createdAt": "2026-03-28T10:00:00Z"
}
```

***

## Available Events

| Event                 | Description                   |
| --------------------- | ----------------------------- |
| `signal.new`          | New daily signal computed     |
| `signal.resolved`     | A prediction outcome resolved |
| `wager.placed`        | Polymarket wager executed     |
| `wager.settled`       | Polymarket wager settled      |
| `attestation.created` | On-chain attestation written  |
| `regime.changed`      | Market regime changed         |

***

## Delivery Format

When an event fires, the server sends a POST request to your registered URL:

```http
POST /bv7x-webhook HTTP/1.1
Content-Type: application/json
X-BV7X-Signature: sha256=a1b2c3d4e5f6...
X-BV7X-Event: signal.new
X-BV7X-Delivery: del_xyz789

{
  "event": "signal.new",
  "data": {
    "signal": "SELL",
    "confidence": 0.615,
    "direction": "DOWN",
    "btcPrice": 66027,
    "regime": "BEAR_TREND",
    "horizon": "7d"
  },
  "timestamp": "2026-03-28T21:35:00Z",
  "deliveryId": "del_xyz789"
}
```

***

## Signature Verification

Every delivery includes an `X-BV7X-Signature` header containing an HMAC-SHA256 signature of the request body, computed with your webhook secret.

**Always verify the signature** before processing the payload.

### Node.js

```javascript
const crypto = require("crypto");

function verifyWebhook(body, signature, secret) {
  const expected = "sha256=" +
    crypto.createHmac("sha256", secret).update(body).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your Express handler:
app.post("/bv7x-webhook", (req, res) => {
  const sig = req.headers["x-bv7x-signature"];
  if (!verifyWebhook(JSON.stringify(req.body), sig, "your-webhook-secret")) {
    return res.status(401).send("Invalid signature");
  }
  // Process the event
  console.log(req.body.event, req.body.data);
  res.status(200).send("OK");
});
```

### Python

```python
import hmac, hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)
```

***

## Retry Policy

* Failed deliveries (non-2xx response) are retried up to 3 times with exponential backoff
* After 3 failures, the webhook is marked inactive
* Your endpoint should respond within 10 seconds

***

## Managing Webhooks

```bash
# List registered webhooks
curl https://bv7x.ai/api/bv7x/webhooks \
  -H "Authorization: Bearer <token>"

# Delete a webhook
curl -X DELETE https://bv7x.ai/api/bv7x/webhooks/wh_abc123 \
  -H "Authorization: Bearer <token>"
```

***

## Next

* [WebSocket](/use-the-signal/read-the-forecast/websocket.md) -- real-time push via persistent connection
* [All Endpoints](/use-the-signal/reference/endpoints.md) -- complete endpoint list
