---
title: Webhooks Reference
path: reference/webhooks
status: published
---

# Webhooks Reference

Outbound webhook management. For the concept overview, see [Events and Webhooks](../03-core-concepts/06-events-and-webhooks.md). For advanced deployment patterns, see [Webhooks Deep Dive](../07-advanced/03-webhooks-deep-dive.md).

**Required permission:** `webhooks:manage`

## GET /v1/webhooks

List webhooks for the tenant.

## POST /v1/webhooks

Register a webhook.

```bash
curl -X POST https://scaigrid.scailabs.ai/v1/webhooks \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-service.example/webhooks",
    "events": ["request.completed", "request.failed", "budget.soft_limit_reached"],
    "secret": "whsec_random_32_chars_or_more",
    "status": "active",
    "max_retries": 5
  }'
```

Fields:

| Field | Notes |
|-------|-------|
| `url` | HTTPS URL to POST events to. Must be publicly reachable |
| `events` | Array of event types to subscribe to |
| `secret` | Shared secret for HMAC signature. Generate with `openssl rand -hex 32` |
| `status` | `active` / `inactive`. Inactive webhooks don't receive deliveries |
| `max_retries` | Max retry attempts on failure. Default 5 |

## GET /v1/webhooks/{webhook_id}

Get webhook details.

## PUT /v1/webhooks/{webhook_id}

Update webhook (URL, events, secret, status, retry policy).

## DELETE /v1/webhooks/{webhook_id}

Delete a webhook. Immediate effect; any in-flight deliveries are discarded.

## POST /v1/webhooks/{webhook_id}/test

Fire a synthetic test event to the webhook URL, for verifying setup.

Response:

```json
{
  "data": {
    "delivery_id": "del_...",
    "status_code": 200,
    "duration_ms": 142,
    "error": null
  }
}
```

## GET /v1/webhooks/{webhook_id}/deliveries

List recent delivery attempts.

Query params: `limit`, `status` (`success` / `failed` / `pending`), `since`.

Response:

```json
{
  "data": {
    "items": [
      {
        "id": "del_...",
        "webhook_id": "wh_...",
        "event_type": "request.completed",
        "status_code": 200,
        "duration_ms": 89,
        "status": "success",
        "error_message": null,
        "created_at": "2026-04-22T14:30:01Z"
      }
    ]
  }
}
```

## Delivery format

Each delivery is an HTTP POST:

```http
POST /your-endpoint HTTP/1.1
Host: your-service.example
Content-Type: application/json
X-ScaiGrid-Signature: sha256=<hmac>
X-ScaiGrid-Event: request.completed
X-ScaiGrid-Delivery: del_xyz
X-ScaiGrid-Timestamp: 1713888601

{
  "event_type": "request.completed",
  "event_id": "evt_abc",
  "source": "inference_service",
  "tenant_id": "tenant_acme",
  "partner_id": "partner_internal",
  "payload": {...},
  "timestamp": "2026-04-22T14:30:00.000Z"
}
```

Return `2xx` within 10 seconds for success. Any other response (including timeout) is a failure.

## Signature verification

HMAC-SHA256 of the raw request body, keyed by the webhook's `secret`. See [Webhooks (concepts)](../03-core-concepts/06-events-and-webhooks.md#signature-verification) for sample code.

## Retry schedule

Failed deliveries retry with exponential backoff:

- Attempt 2: 30 seconds after first failure
- Attempt 3: 2 minutes
- Attempt 4: 10 minutes
- Attempt 5: 30 minutes
- Attempt 6: 2 hours

After `max_retries` attempts, the delivery is marked permanently failed.

After 50 consecutive failures on any events, the webhook is auto-disabled. You get a `webhook.auto_disabled` event (if another webhook subscribes to it) and an admin UI alert.

## Event types

See [Events and Webhooks](../03-core-concepts/06-events-and-webhooks.md) for the full event type list. Common ones:

- `request.completed`, `request.failed`
- `budget.soft_limit_reached`, `budget.hard_limit_reached`
- `scaikey.user.created`, `scaikey.user.updated`
- Module-specific: `scaicore.*`, `scaiqueue.*`, `scaibunker.*`, `scaimatrix.*`

## Replay

Replay events that missed delivery (e.g., after your endpoint was down):

```bash
curl -X POST "https://scaigrid.scailabs.ai/v1/webhooks/{webhook_id}/replay?since=2026-04-22T00:00:00Z" \
  -H "Authorization: Bearer $TOKEN"
```

Replays send events still in the event bus (default retention: 100K entries or 7 days, whichever is first).

## Related

- [Events and Webhooks](../03-core-concepts/06-events-and-webhooks.md)
- [Webhooks Deep Dive](../07-advanced/03-webhooks-deep-dive.md)
- [Audit Log](./09-audit-log.md)
