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

# Webhooks

> Learn how to use webhooks to receive real-time updates from Moonbase.

Moonbase webhooks enable real-time notifications about events in Moonbase, such as when an item is created, when a program message is opened, or a meeting is held. Webhooks are delivered to a configured HTTP endpoint.

## Quick Start

Creating your first webhook with Moonbase.

### 1. Create an endpoint

Use the [Webhooks API](../api-reference/webhook-endpoints/create) to register the webhook endpoint:

```bash theme={null}
curl -X POST https://api.moonbase.ai/v0/webhook_endpoints \
  -H "Authorization: Bearer MOONBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/moonbase",
    "subscriptions": [
      {"event_type": "activity/item_created"},
      {"event_type": "activity/meeting_held"}
    ]
  }'
```

The response will include the endpoint's unique `secret` (prefixed with `whsec_`). **Store this secret securely**—required to verify incoming webhooks. This is the only time the secret will be shown.

### 2. Expose an HTTPS route

Webhook endpoints must:

* Be publicly accessible via HTTPS
* Accept POST requests with `application/json` content
* Respond within 30 seconds to avoid timeouts

### 3. Verify the signature

Always verify the webhook signature before processing any data. This ensures:

* The request genuinely comes from Moonbase
* The payload hasn't been tampered with
* Protection against replay attacks

Key requirements:

* Use the **raw request body** (before JSON parsing)
* Verify the signature **before** any other processing
* Reject requests with invalid signatures immediately

See the [signature verification section](#verifying-webhook-signatures) for implementation details.

### 4. Process the payload

After successful verification, parse and process the JSON payload.

### 5. Respond promptly

Return a `2XX` status code (typically `200` or `204`) to acknowledge receipt:

* Respond as quickly as possible (within 30 seconds)
* Process time-consuming operations asynchronously

If Moonbase doesn't receive a `2XX` response, it will retry delivery according to the [retry schedule](#delivery-and-retry-logic).

## Configuration

Additional configurations for webhooks.

### Payload Format

Each payload includes:

* `id`: Unique event identifier
* `occurred_at`: ISO 8601 timestamp indicating when the event occurred.
* `type`: Event type (e.g., `activity/item_created`)
* Related objects (item, collection, etc.)

```json Example Payload lines theme={null}
{
  "id": "1CLJt2v2bnDhMVZzehdb6A",
  "occurred_at": "2025-02-17T15:59:55.000Z",
  "type": "activity/item_created",
  "item": {
    "id": "1CLJt2uzNLR8B4AnQ3vJ3B",
    "type": "item",
    "collection": {
      "id": "1CLJt2uzcick5mf96Lzt9x",
      "type": "collection",
      "ref": "people"
    }
  }
}
```

## Verifying webhook signatures

Never process webhook data without first verifying its authenticity. Verification ensures that the request came from Moonbase and hasn't been tampered with.

### How signatures work

Moonbase uses the [Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks) specification for signing webhooks:

1. Each endpoint has a unique signing secret (format: `whsec_0{version}{44-char-base58}`)
2. Every webhook request includes an HMAC-SHA256 signature in the `webhook-signature` header
3. The signature covers the event ID, timestamp, and raw request body

The signature algorithm:

```
signature = HMAC-SHA256(secret, `${webhook_id}.${webhook_timestamp}.${raw_payload}`)
```

### Security best practices

1. **Store secrets securely**: Use environment variables or a secrets management service—never commit secrets to version control
2. **Use raw request bodies**: The signature is computed on the exact bytes sent—any modification (even whitespace) will cause verification to fail
3. **Verify timing**: Check that the timestamp is recent (within 5 minutes) to prevent replay attacks
4. **Reject failures**: If verification fails for any reason, reject the request with a `400` or `401` status
5. **Log failures**: Monitor verification failures as they may indicate security issues

### HTTP Headers

Webhook requests include the following Standard Webhooks headers:

* `webhook-id`: Event ID (used for idempotency and doesn't change between retries)
* `webhook-timestamp`: Unix timestamp when the request was sent
* `webhook-signature`: HMAC-SHA256 signature for verification
* `content-type`: `application/json`

## Delivery and Retry Logic

Moonbase ensures reliable webhook delivery with automatic retries and intelligent backoff strategies.

### Response handling

The endpoint's HTTP response determines how Moonbase handles the delivery:

| Status Code             | Behavior          | Notes                                       |
| ----------------------- | ----------------- | ------------------------------------------- |
| `2XX`                   | Success           | Delivery marked complete, no retries        |
| `410 Gone`              | Permanent failure | Endpoint automatically disabled, no retries |
| `429 Too Many Requests` | Rate limited      | Honors `Retry-After` header if present      |
| All other non-`2XX`     | Temporary failure | Automatic retry with exponential backoff    |

### Retry schedule

Failed deliveries are retried for up to 24 hours using exponential backoff with 10% jitter to prevent thundering herd issues:

| Attempt | Delay        | Cumulative Time | Notes                                  |
| ------- | ------------ | --------------- | -------------------------------------- |
| 1       | Immediate    | 0 seconds       | Initial delivery                       |
| 2       | \~30 seconds | \~30 seconds    | 30s + random jitter (0-3s)             |
| 3       | \~1 minute   | \~1.5 minutes   | 60s + random jitter (0-6s)             |
| 4       | \~2 minutes  | \~3.5 minutes   | 120s + random jitter (0-12s)           |
| 5       | \~4 minutes  | \~7.5 minutes   | 240s + random jitter (0-24s)           |
| 6       | \~8 minutes  | \~15.5 minutes  | 480s + random jitter (0-48s)           |
| 7       | \~16 minutes | \~31.5 minutes  | 960s + random jitter (0-96s)           |
| 8       | \~32 minutes | \~1 hour        | 1920s + random jitter (0-192s)         |
| 9+      | \~1 hour     | Varies          | 3600s + random jitter (0-360s), capped |

**Key points:**

* Maximum individual retry delay: 1 hour
* Total retry window: 24 hours
* Jitter: 10% of base delay to distribute load
* Guaranteed: At least one delivery attempt per hour during the retry window

### Handling failures

To minimize failed deliveries:

1. **Respond quickly**: Return a `2XX` status within 30 seconds
2. **Implement idempotency**: Use the `webhook-id` header to handle duplicate deliveries
3. **Monitor endpoint**: Track success rates and response times
4. **Use proper status codes**: Return `410` if the endpoint is permanently decommissioned
5. **Handle rate limits**: Return `429` with `Retry-After` header if you need to throttle

## Idempotency

Webhooks guarantee at-least-once message delivery. Moonbase includes a `webhook-id` header containing a unique identifier for each event. This ID remains the same across all retry attempts for a failed webhook, enabling applications to handle duplicate deliveries by tracking processed event IDs.

## Data Retention

Event payloads and delivery response data are retained for 30 days before being automatically purged from Moonbase systems. This retention period allows for webhook replay and troubleshooting while maintaining data privacy compliance.
