> ## Documentation Index
> Fetch the complete documentation index at: https://trunk-4cab4936-docs-swift-test-xunit-and-xcresult-locations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Use webhooks to automate custom flaky test workflows

Trunk provides webhooks for you to build custom integrations to automate workflows, like notifying your team when a test becomes flaky or automatically creating tickets to investigate flaky tests. Trunk provides built-in connectors for [Linear](./linear-integration) and [Jira](./jira-integration) to automate ticket creation, and webhooks let you build custom integrations for use cases that are not supported out of the box.

<Info>
  **Creating tickets in Linear or Jira?** Trunk's built-in [automatic ticketing](/flaky-tests/management/ticketing/automatic-ticketing) is the recommended approach — it produces richer ticket bodies (failure history, impact, common failure reasons, code owners), manages the full ticket lifecycle (create, reopen, close), and has full dashboard support with tickets linked back to their test cases. Use webhooks for custom workflows or platforms without a built-in integration.
</Info>

<Info>
  For Merge Queue webhook events (`pull_request.*` and `pull_request_batch.*`), see the [Merge Queue webhooks reference](/merge-queue/webhooks).
</Info>

[Svix](https://docs.svix.com/) powers webhooks for Trunk. You'll be using Svix to configure webhooks and you should familiarize yourself with the [Svix App Portal docs](https://docs.svix.com/app-portal) to learn more.

## Supported Events

Trunk lets you create custom workflows with **event-triggered webhooks**. Flaky Tests events are named with a `test_case` prefix. You can find all the events that Trunk supports in the event catalog:

<Card horizontal icon="https://mintcdn.com/trunk-4cab4936-docs-swift-test-xunit-and-xcresult-locations/Is5Fn27WF90gfveU/assets/_shared/svix.svg?fit=max&auto=format&n=Is5Fn27WF90gfveU&q=85&s=97b196be0212837e9ef7c0c06b6efc5f" title="Webhook Events | trunk.io - Svix" href="https://www.svix.com/event-types/us/org_2eQPL41Ew5XSHxiXZIamIUIXg8H/#v2.test_case.status_changed" width="347" height="347" data-path="assets/_shared/svix.svg">
  [www.svix.com](http://www.svix.com)
</Card>

Trunk publishes three Flaky Tests event types to Svix. Each event includes a full JSON schema with field descriptions visible in the Svix app portal.

## Test collection events

Events for [test collections](/flaky-tests/test-collections) carry the same event types, with one addition to the payload and one thing you cannot do with it.

**Telling the two apart.** A collection event carries a `test_collection` object — its ID and a link to the collection. Repository events don't. That object is the supported way to distinguish them.

**You cannot deduplicate on `test_case.id`.** Collection and repository events do not share a test-case ID space, so the same underlying test arrives under two unrelated IDs. `repository.id` is the only handle common to both, and it is omitted rather than guessed when an upload carries no repository.

**While you are migrating, collection events are off.** A repository and a collection with monitors over the same tests detect independently, so one detection can produce two events. Switch collection events on from **Settings** → **Organization** → **Webhooks** once your consumer handles the payloads above. It is one switch for every collection event, not one per event type, and it disappears once you have finished migrating — at that point collection events are simply sent. See the [migration guide](/flaky-tests/get-started/migrate-to-test-collections#webhooks-while-you-migrate).

## Event payloads

### `test_case.monitor_status_changed`

Emitted when a monitor activates or resolves for a test case.

| Field                   | Type              | Description                                                         |
| ----------------------- | ----------------- | ------------------------------------------------------------------- |
| `type`                  | string            | Always `test_case.monitor_status_changed`                           |
| `timestamp`             | string (ISO 8601) | When the event occurred                                             |
| `monitor.id`            | string (UUID)     | Unique identifier for the monitor                                   |
| `monitor.type`          | string            | The type of monitor (e.g., `pass_on_retry`)                         |
| `monitor.status`        | string            | Current monitor status (`active` or `resolved`)                     |
| `evidence`              | object            | Data supporting the status change; structure varies by monitor type |
| `repository.id`         | string (UUID)     | Unique identifier for the repository                                |
| `repository.html_url`   | string            | URL of the repository                                               |
| `test_case.id`          | string (UUID)     | Stable unique identifier for the test                               |
| `test_case.name`        | string            | Name of the test                                                    |
| `test_case.classname`   | string            | Test classname                                                      |
| `test_case.file_path`   | string            | File path of the test                                               |
| `test_case.html_url`    | string            | URL to the test detail page in Trunk                                |
| `test_case.codeowners`  | array of strings  | Code owners associated with the test                                |
| `test_case.quarantined` | boolean           | Whether the test is quarantined                                     |
| `test_case.variant`     | string            | Test variant name                                                   |

### `v2.test_case.status_changed`

Emitted when a test case changes status (e.g., becomes flaky or is resolved), as triggered by a monitor.

| Field                         | Type              | Description                                      |
| ----------------------------- | ----------------- | ------------------------------------------------ |
| `type`                        | string            | Always `v2.test_case.status_changed`             |
| `timestamp`                   | string (ISO 8601) | When the event occurred                          |
| `previous_status`             | string            | The prior status of the test case                |
| `new_status`                  | string            | The updated status of the test case              |
| `triggered_by.monitor_id`     | string (UUID)     | Unique identifier of the triggering monitor      |
| `triggered_by.monitor_type`   | string            | Type of monitor that triggered the change        |
| `triggered_by.monitor_status` | string            | Status of the monitor at the time of the trigger |
| `repository`                  | object            | See `repository` fields above                    |
| `test_case`                   | object            | See `test_case` fields above                     |

### `test_case.investigation_completed`

Emitted when an AI-powered flaky test analysis finishes for a test case.

| Field                | Type              | Description                                                                 |
| -------------------- | ----------------- | --------------------------------------------------------------------------- |
| `type`               | string            | Always `test_case.investigation_completed`                                  |
| `investigation_id`   | string (UUID)     | Unique identifier for the investigation                                     |
| `trigger`            | string            | How the investigation was initiated. One of `AUTOMATIC`, `MANUAL`, or `MCP` |
| `confidence`         | number            | Overall confidence score (0-1) for the findings                             |
| `created_at`         | string (ISO 8601) | When the investigation completed                                            |
| `markdown_summary`   | string            | Markdown-formatted summary of findings and recommendations                  |
| `failure_message`    | string            | The original failure message that triggered the investigation               |
| `facts`              | array             | Facts discovered during the investigation                                   |
| `facts[].fact_type`  | string            | Category of the fact (e.g., `GIT_BLAME`)                                    |
| `facts[].content`    | string            | Detailed description with citations to supporting evidence                  |
| `facts[].confidence` | number            | Confidence score (0-1) for this individual fact                             |
| `repository`         | object            | See `repository` fields above                                               |
| `test_case`          | object            | See `test_case` fields above                                                |

Citations in `markdown_summary` and `facts[].content` are delivered as fully rendered links to the supporting evidence, so you can consume these fields directly without resolving placeholder tags.

**Delivery reliability.** If the webhook delivery provider rate-limits a request, Trunk automatically retries with exponential backoff, so a transient spike rarely drops an event. This applies to every Flaky Tests webhook event and needs no configuration on your side.

You can also find guides for specific examples here:

<Columns cols={2}>
  <Card title="Alert When a Test Escalates" href="../recipes/alert-on-test-escalation" />

  <Card title="Send a Slack Message" href="./slack-integration" />

  <Card title="Create a GitHub Issue" href="./github-issues-integration" />

  <Card title="Send a Microsoft Teams Message" href="./microsoft-teams-integration" />

  <Card title="Create a Linear Issue" href="./linear-integration" />

  <Card title="Create a Jira Issue" href="./jira-integration" />
</Columns>
