> For the complete documentation index, see [llms.txt](https://academy.shade.inc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://academy.shade.inc/developers/guides/webhooks.md).

# Webhooks

Enable webhooks to listen to changes in Shade

Shade sends webhook events to notify your application when resources are created, updated, or deleted across your workspace. You can subscribe to specific event types to build integrations, sync external systems, or trigger custom workflows.

{% hint style="info" %}
To go the other way and have an outside service trigger work in Shade, or to call an external API from a workflow without running your own server, use [webhooks in automations](#webhooks-in-automations).
{% endhint %}

### Accessing Webhooks from the App and Opening the Webhooks Dashboard

Shade offers a full webhooks dashboard that you can easily configure and manage all of your webhook endpoints.

<figure><img src="https://2149326901-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F78QKMeD8RCfROVEmgJMO%2Fuploads%2FR4RmzKW5rpbbLbaEUL4R%2FScreenshot%202026-05-13%20at%203.17.47%E2%80%AFPM.png?alt=media&#x26;token=ba7f02d6-b3af-4348-b4cd-0fdf7d4fcf4e" alt=""><figcaption></figcaption></figure>

### Creating an Initial Webhook Response Endpoint

Once you have opened the dashboard, you can configure a new endpoint under the "Endpoints" section. From there, you can subscribe to any of our events and send the output to your endpoint URL for further processing.

<figure><img src="https://2149326901-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F78QKMeD8RCfROVEmgJMO%2Fuploads%2FO7ZEXXislx0aONGv5PH8%2FScreenshot%202026-05-13%20at%203.18.30%E2%80%AFPM.png?alt=media&#x26;token=af8c6abc-c99a-45db-af11-598f59d6c263" alt=""><figcaption></figcaption></figure>

### Verifying Webhook Signatures

Shade delivers webhooks through [Svix](https://www.svix.com/). Every request includes three headers:

* `svix-id`: A unique ID for the message
* `svix-timestamp`: When the message was sent
* `svix-signature`: The signature of the message

To confirm a request really came from Shade, verify it with one of the [Svix libraries](https://docs.svix.com/receiving/verifying-payloads/how) using your endpoint's signing secret, which you can find on the endpoint's page in the webhooks dashboard. Verify against the raw request body, before parsing the JSON.

```python
from svix.webhooks import Webhook

wh = Webhook("whsec_...")  # your endpoint's signing secret
payload = wh.verify(raw_body, request_headers)  # raises an error if the signature is invalid
```

If your endpoint doesn't respond with a 2xx status, Svix automatically retries delivery on its standard retry schedule. You can see delivery attempts and resend messages from the dashboard.

### Event Format

Every webhook delivers a JSON payload with a consistent envelope structure:

```json
{
  "event_type": "resource_type.action",
  "resource": {
    "type": "resource_type",
    "id": "uuid"
  },
  "user": {
    "id": "uuid",
    "email": "jane@example.com",
    "name": "Jane Smith"
  },
  "workspace": {
    "id": "uuid",
    "name": "My Workspace",
    "domain": "myworkspace"
  },
  "drive": {
    "id": "uuid",
    "name": "My Drive",
    "identifier": "my-drive"
  },
  "payload": {}
}
```

### Current Running List of Planned / Supported Webhooks

{% hint style="info" %}
You can take a look at all of the endpoints available via the Webhooks dashboard accesible via our app and heading to `Event Catalog`
{% endhint %}

| Field        | Type             | Description                                                                            |
| ------------ | ---------------- | -------------------------------------------------------------------------------------- |
| `event_type` | `string`         | The event identifier in `resource_type.action` format.                                 |
| `resource`   | `object`         | The resource type and ID the event relates to.                                         |
| `user`       | `object \| null` | The user who performed the action. `null` for system-initiated events (e.g. indexing). |
| `workspace`  | `object`         | The workspace the event occurred in.                                                   |
| `drive`      | `object \| null` | The drive the event occurred in. `null` for workspace-level events.                    |
| `payload`    | `object`         | The full resource data at the time of the event. Fields vary by resource type.         |

***

### Available Events

#### Assets

Events triggered by file system changes detected during drive indexing. The `user` field is `null` for these events since they are system-initiated.

| Event            | Description                                                                    |
| ---------------- | ------------------------------------------------------------------------------ |
| `asset.created`  | A new file or folder was detected in the drive.                                |
| `asset.modified` | An existing file was modified.                                                 |
| `asset.moved`    | A file was moved or renamed. `payload` includes `path` and `to_path`.          |
| `asset.deleted`  | A file or folder was deleted from the drive, or moved to the trash.            |
| `asset.uploaded` | A file was uploaded to the drive.                                              |
| `asset.updated`  | A metadata attribute was updated on an asset. Fired once per attribute change. |

#### Asset Processing

Events fired when background processing jobs complete. The `user` field is `null` for these events.

| Event                     | Description                                      |
| ------------------------- | ------------------------------------------------ |
| `preview.completed`       | Preview image generation finished for an asset.  |
| `proxy.completed`         | Video proxy generation finished for an asset.    |
| `audio_proxy.completed`   | Audio proxy generation finished for an asset.    |
| `transcription.completed` | Transcription finished for an audio/video asset. |

#### Collections

| Event                      | Description                                                 |
| -------------------------- | ----------------------------------------------------------- |
| `collection.created`       | A new collection was created (includes duplications).       |
| `collection.updated`       | A collection's name, description, or settings were changed. |
| `collection.deleted`       | A collection was deleted.                                   |
| `collection.items_added`   | Assets were added to a collection.                          |
| `collection.items_removed` | Assets were removed from a collection.                      |

#### Comments

| Event                | Description                                     |
| -------------------- | ----------------------------------------------- |
| `comment.created`    | A new comment or reply was created on an asset. |
| `comment.updated`    | A comment's text was edited.                    |
| `comment.deleted`    | A comment was deleted.                          |
| `comment.resolved`   | A comment thread was marked as resolved.        |
| `comment.unresolved` | A resolved comment thread was reopened.         |
| `comment.reacted`    | A reaction was added to a comment.              |

#### Public Links

| Event                 | Description                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------- |
| `public_link.created` | A new public share link was created.                                                               |
| `public_link.updated` | A public share link's settings were changed (permissions, password, expiration, view limit, etc.). |
| `public_link.deleted` | A public share link was removed.                                                                   |

#### Drive Members

| Event                  | Description                                                |
| ---------------------- | ---------------------------------------------------------- |
| `drive_invite.created` | A user was invited to a drive or granted access to a path. |
| `drive_invite.updated` | A user's drive role or path permissions were changed.      |
| `drive_invite.deleted` | A user was removed from a drive or lost access to a path.  |

#### Workspace Members

| Event                      | Description                            |
| -------------------------- | -------------------------------------- |
| `workspace_invite.created` | A user was invited to the workspace.   |
| `workspace_invite.updated` | A user's workspace role was changed.   |
| `workspace_invite.deleted` | A user was removed from the workspace. |

#### Drives

| Event           | Description                                                              |
| --------------- | ------------------------------------------------------------------------ |
| `drive.created` | A new drive was created in the workspace.                                |
| `drive.updated` | A drive's details (such as its name, description, or icon) were changed. |
| `drive.deleted` | A drive was deleted.                                                     |

### Webhooks in automations

[Automations](https://academy.shade.inc/automations-and-custom-objects/automations) can receive webhooks from other services and send HTTP requests to them, with no server of your own.

#### Receiving a webhook

Start an automation with the **Webhook Received** trigger to run it whenever another service sends a request to its webhook URL. Use it to start a workflow from a form submission, a project management tool, a CI pipeline, or your own app.

1. Create an automation and choose **Webhook Received** as the trigger.
2. Copy the **Webhook URL** from the trigger's settings.
3. Under **Output fields**, add the fields from the request body you want to use in later steps. **Path** is the field's location in the JSON body, such as `data.title`. Each field you add becomes a variable you can insert in later steps.
4. Activate the automation. A draft automation's URL returns `404`.

Send the request as a `POST` with a JSON object body:

```bash
curl -X POST "YOUR_WEBHOOK_URL" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "title": "New issue logged", "reporter": "jordan@example.com" } }'
```

Shade responds right away with `{"status": "queued"}`, and the automation runs in the background. Check the automation's **Runs** tab to see each run.

| Setting                    | Description                                                                                          |
| -------------------------- | ---------------------------------------------------------------------------------------------------- |
| **Require authentication** | Callers must send `Authorization: Bearer <auth token>`. Requests without the right token get a `401` |
| **Auth token**             | The token callers must send. Shade generates one if you leave it empty                               |

The request body must be a JSON object of up to 128 KB. If a service verifies endpoints by sending a body of exactly `{"challenge": "<value>"}`, as monday.com does, Shade replies with the same challenge instead of running the automation.

{% hint style="warning" %}
Anyone with the URL can trigger the automation if **Require authentication** is off. Keep it on unless the sending service can't set headers.
{% endhint %}

#### Sending an HTTP request

Add a **Send HTTP Request** action to call an external API from an automation: post to Slack or Teams, update a ticket, or notify your own service when files are uploaded, tagged, or transcribed.

| Setting              | Description                                                                                                                                                 |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Method**           | `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`                                                                                                                  |
| **URL**              | The address to call                                                                                                                                         |
| **Headers**          | Extra headers, such as `Authorization: Bearer <token>` for the receiving API                                                                                |
| **Query parameters** | Added to the URL                                                                                                                                            |
| **Body**             | A JSON body, usually for `POST`, `PUT`, or `PATCH`. Shade sets `Content-Type: application/json` when the body is valid JSON and you haven't set it yourself |
| **Timeout (ms)**     | How long to wait for a response, up to 120,000. Defaults to 30,000                                                                                          |

Type `{` or use **Insert variable** in any of these fields to include values from earlier steps, such as the asset's name or path, or an output field from a **Webhook Received** trigger.

The step's output includes the response `status`, the response body as `data` (parsed as JSON when possible), and a few non-sensitive response headers, which later steps can use. A response with an error status, such as `404` or `500`, doesn't stop the automation, so use `status` in later steps if they depend on the call succeeding.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://academy.shade.inc/developers/guides/webhooks.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
