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

# Webhooks

> Get an HTTP request, a Slack message or a Discord message when something happens in your workspace.

A webhook tells you when something happens in your workspace, as it happens: an instance is ready, a job finished, a budget is close to its limit, the balance is running low. Runcrate sends each event to the endpoints you add, so a pipeline can react without polling the API and your team hears about it where it already works.

Each endpoint uses one of three channels:

| Channel | What arrives | Signed |
| - | - | - |
| **Webhook** | A `POST` of the event as JSON to your own HTTPS server. | Yes, with HMAC-SHA256. See [verifying signatures](/docs/webhooks/verifying-signatures). |
| **Slack** | A message in a Slack channel, through a Slack incoming webhook. See [Slack](/docs/webhooks/slack). | No. The URL is the secret. |
| **Discord** | A message in a Discord channel, through a Discord channel webhook. See [Discord](/docs/webhooks/discord). | No. The URL is the secret. |

All three get the same events, with the same retries and the same delivery log. Webhooks are set per workspace and cover every environment in it.

## Quickstart

Only workspace owners and admins can add or change endpoints. Other members can see the list and the delivery log.

**1. Open Settings > Webhooks**

Go to [workspace settings](https://runcrate.ai/dashboard/settings/webhooks) and find **Webhooks**. Select **Add endpoint**.

**2. Pick a channel**

Under **Where it goes**, choose **Webhook** for your own server, or **Slack** or **Discord** for a channel.

**3. Paste the URL**

For a webhook, paste your endpoint's public `https://` URL. For Slack or Discord, paste the webhook URL you copied from it ([Slack steps](/docs/webhooks/slack), [Discord steps](/docs/webhooks/discord)).

**4. Choose events**

Under **Events**, keep **All events**, or select **Choose events** and tick the ones you want. **What arrives** shows the exact body for any event.

**5. Send a test event**

Select **Send a test event**. A [`webhook.test`](/docs/webhooks/events) event goes to the URL at once and you see whether it landed, or a sentence about why it did not.

**6. Copy the signing secret**

For a webhook, the signing secret (it starts with `whsec_`) is shown once, under **Copy the signing secret now**. Store it in your secret manager, then select **I have copied it**. Slack and Discord endpoints have no secret.

## The envelope

Every event has the same shape. A signed webhook receives exactly this JSON as the request body, here for `instance.runtime_ending`:

```json theme={"theme":{"light":"github-light","dark":"catppuccin-mocha"}}
{
  "id": "6f1d3c2a-8a4e-4b7f-9a51-2f0c1e7d9004",
  "type": "instance.runtime_ending",
  "api_version": "2026-10-20",
  "created_at": "2026-10-20T14:02:11.000Z",
  "workspace_id": "a3c9e2f0-1b7d-4e55-8f20-6d4b9c1a7e33",
  "environment_id": "e81b4f6a-2c3d-4a9e-b710-5f8c2d1e9a04",
  "data": {
    "deployment_id": "7d2e9c41-5b3a-4f60-8e17-c4a0b9d2f655",
    "deployment_name": "train-llama-8b",
    "environment_id": "e81b4f6a-2c3d-4a9e-b710-5f8c2d1e9a04",
    "auto_stop_at": "2026-10-20T14:12:11.000Z",
    "max_runtime_minutes": 240
  }
}
```

| Field | Type | Meaning |
| - | - | - |
| `id` | string (UUID) | The event's id. The same on every retry and every redelivery, so use it to drop duplicates. |
| `type` | string | What happened, as `resource.event`, for example `budget.reached`. See [events](/docs/webhooks/events). |
| `api_version` | string | The date of the event format. See [versioning](/docs/webhooks/events#versioning). |
| `created_at` | string (ISO 8601) | When the event happened, in UTC. Use it to order events. |
| `workspace_id` | string (UUID) | The workspace the event belongs to. |
| `environment_id` | string (UUID) or `null` | The environment the event belongs to. `null` for workspace-wide events: `balance.*`, `credits.added`, `storage.*` and `webhook.*`. |
| `data` | object | The event's details. Its keys depend on `type`, and new keys can appear, so ignore ones you do not use. |

Each request also carries these headers:

| Header | Value |
| - | - |
| `Content-Type` | `application/json` |
| `User-Agent` | `Runcrate-Webhooks/1.0` |
| `Runcrate-Event` | The event `type`, so you can route before parsing the body. |
| `Runcrate-Delivery` | The id of this delivery. A redelivery gets a new one; the event `id` stays the same. |
| `Runcrate-Signature` | `t=<unix seconds>,v1=<hex HMAC>`. Webhook channel only. See [verifying signatures](/docs/webhooks/verifying-signatures). |

## Limits

* Up to **10 endpoints** per workspace, across all three channels.
* Webhook URLs must be public `https://` addresses. Addresses inside a private network or on `localhost` are refused; to test against your own machine, see [testing locally](/docs/webhooks/testing-locally).
* Answer within **10 seconds** with any `2xx`. Anything else is retried, up to 8 attempts over about 3 hours 40 minutes. See [retries](/docs/webhooks/retries).
* An endpoint that has failed for 3 days with no success (and at least 10 failed attempts), or has given up on 20 events in a row, is turned off. See [automatic turn-off](/docs/webhooks/retries#automatic-turn-off).
* **Send a test event**: 10 per person per 10 minutes. **Redeliver**: 10 per person and 30 per workspace per 10 minutes.
* Deliveries stay in the delivery log for 30 days.

## Learn more

> **[Events](/docs/webhooks/events)**
>
> Every event type, its fields and an example.

> **[Verifying signatures](/docs/webhooks/verifying-signatures)**
>
> Check the `Runcrate-Signature` header in Node.js, Python and Go.

> **[Retries and the delivery log](/docs/webhooks/retries)**
>
> The retry schedule, Redeliver and automatic turn-off.

> **[Testing locally](/docs/webhooks/testing-locally)**
>
> Receive events on your own machine through a tunnel.

> **[Slack](/docs/webhooks/slack)**
>
> Post events to a Slack channel.

> **[Discord](/docs/webhooks/discord)**
>
> Post events to a Discord channel.

> **[Best practices](/docs/webhooks/best-practices)**
>
> Answer fast, dedupe on id, keep the secret safe.

> **[Spend guardrails](/docs/instances/guardrails)**
>
> The budgets and auto stops behind several of these events.


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