# Sending webhook

Outgoing webhooks are a powerful feature for advanced users that can be used to integrate BugBug into your current workflow, such as sending custom notifications to your team's communicator, like Slack.

Before proceeding to the next step, set up a webhook in your external service. You will need the webhook configuration to populate the form fields.

{% hint style="info" %}
**Note**: You can use built-in variables in any field, e.g., **{{testRunId}}**.
{% endhint %}

### Set basic request data

In the first two fields, define the request **method** and the **webhook URL**. Currently, we support the most popular webhook request methods like POST and GET.

<figure><img src="/files/9pkqqh1yMGA6Wet1a7el" alt=""><figcaption><p>Method and Webohook URL fields on the setup screen</p></figcaption></figure>

### Define POST request body message

The **Body** field is optional and consumes JSON data. Its value depends on your needs and your external service provider's requirements.

If you need to send additional data through the webhook request, it's the best place to do so.

### Testing a webhook alert

Before creating a new webhook alert, you can test it by clicking the **"Trigger Alert"** button.

It's a good practice to do this. It helps you avoid unexpected errors in the future, such as invalid credentials or an incorrect request body format.

<figure><img src="/files/bViHr6UaHyGyv9NQchqi" alt=""><figcaption><p>Verify alert configuration</p></figcaption></figure>

### Define the POST request body message

When setting up the *Body* of your webhook, you can use variables available in the specific event context. Knowing this, for instance, you can set an alert that sends the test name via the POST method, with the body containing a variable that reflects the finished test's name.\\

<figure><img src="/files/khUDDGoKOGzJA4uhL8aV" alt=""><figcaption><p>Request body with a bult-in variable</p></figcaption></figure>

Reference for all available variables in webhook notification templates.

#### Common Variables (all context types)

| Variable               | Type   | Description                                                |
| ---------------------- | ------ | ---------------------------------------------------------- |
| `{{eventId}}`          | UUID   | Unique event ID for deduplication                          |
| `{{eventName}}`        | string | Notification event (e.g., `testFinished`, `suiteFinished`) |
| `{{status}}`           | string | Run status (`passed`, `failed`, `error`, etc.)             |
| `{{profileName}}`      | string | Run profile name                                           |
| `{{runMode}}`          | string | Run mode (`cloud`, `local`, `recording`)                   |
| `{{started}}`          | string | ISO 8601 start timestamp                                   |
| `{{finished}}`         | string | ISO 8601 end timestamp                                     |
| `{{durationMs}}`       | int    | Duration in milliseconds (e.g., `330500`)                  |
| `{{triggeredBy}}`      | string | Who triggered the run (`user`, `scheduler`, `api`)         |
| `{{organizationId}}`   | UUID   | Organization ID                                            |
| `{{organizationName}}` | string | Organization name                                          |
| `{{projectId}}`        | UUID   | Project ID                                                 |
| `{{projectName}}`      | string | Project name                                               |
| `{{projectUrl}}`       | URL    | Link to project in webapp                                  |
| `{{timestampMs}}`      | int    | Current epoch timestamp in milliseconds                    |
| `{{timestamp}}`        | int    | Alias for `timestampMs` (backward compatibility)           |
| `{{schemaVersion}}`    | string | Webhook payload schema version (e.g., `v1`)                |
| `{{objectsLimit}}`     | int    | Maximum number of items per list (e.g., `10`)              |

#### Test Run Variables

Available when the webhook is triggered by a test run event.

| Variable                  | Type   | Description                                                                         |
| ------------------------- | ------ | ----------------------------------------------------------------------------------- |
| `{{testName}}`            | string | Test name                                                                           |
| `{{testId}}`              | UUID   | Test ID                                                                             |
| `{{testRunId}}`           | UUID   | Test run ID                                                                         |
| `{{testRunUrl}}`          | URL    | Link to test run details in webapp                                                  |
| `{{testUrl}}`             | URL    | Link to test definition in webapp                                                   |
| `{{browser}}`             | string | Combined browser string (e.g., `"Chrome 120.0"`)                                    |
| `{{browserName}}`         | string | Browser name                                                                        |
| `{{browserVersion}}`      | string | Browser version                                                                     |
| `{{os}}`                  | string | Operating system name                                                               |
| `{{screenSizeType}}`      | string | Screen size type (`desktop`, `mobile`, etc.)                                        |
| `{{extensionVersion}}`    | string | BugBug extension version                                                            |
| `{{failedStepUrl}}`       | URL    | Deep-link to first failed step (only for failed/errored runs)                       |
| `{{failedStepId}}`        | UUID   | Step Id of failed step                                                              |
| `{{failedStepErrorCode}}` | string | [Error code](/debugging-tests/error-codes.md) that represents problem with the step |
| `{{suiteId}}`             | UUID   | Parent suite ID (if run within a suite)                                             |
| `{{suiteRunId}}`          | UUID   | Parent suite run ID                                                                 |
| `{{suiteName}}`           | string | Parent suite name                                                                   |
| `{{suiteRunUrl}}`         | URL    | Link to parent suite run details                                                    |
| `{{scheduleId}}`          | UUID   | Parent schedule ID (if run within a schedule)                                       |
| `{{schedulerRunId}}`      | UUID   | Parent scheduler run ID                                                             |
| `{{scheduleName}}`        | string | Parent schedule name                                                                |

#### Suite Run Variables

Available when the webhook is triggered by a suite run event.

| Variable                    | Type   | Description                                      |
| --------------------------- | ------ | ------------------------------------------------ |
| `{{suiteId}}`               | UUID   | Suite ID                                         |
| `{{suiteRunId}}`            | UUID   | Suite run ID                                     |
| `{{suiteName}}`             | string | Suite name                                       |
| `{{suiteRunUrl}}`           | URL    | Link to suite run details                        |
| `{{suiteUrl}}`              | URL    | Link to suite configuration                      |
| `{{failedTestsCount}}`      | int    | Number of failed tests                           |
| `{{passedTestsCount}}`      | int    | Number of passed tests                           |
| `{{erroredTestsCount}}`     | int    | Number of errored tests                          |
| `{{totalTestsCount}}`       | int    | Total number of tests (including skipped)        |
| `{{failedTests}}`           | JSON   | Failed tests details (see structure below)       |
| `{{passedTests}}`           | JSON   | Passed tests details (see structure below)       |
| `{{erroredTests}}`          | JSON   | Errored tests details (see structure below)      |
| `{{failedTestsTruncated}}`  | bool   | `true` if failed tests list was truncated to 10  |
| `{{passedTestsTruncated}}`  | bool   | `true` if passed tests list was truncated to 10  |
| `{{erroredTestsTruncated}}` | bool   | `true` if errored tests list was truncated to 10 |
| `{{scheduleId}}`            | UUID   | Parent schedule ID (if run within a schedule)    |
| `{{schedulerRunId}}`        | UUID   | Parent scheduler run ID                          |
| `{{scheduleName}}`          | string | Parent schedule name                             |

#### Schedule Run Variables

Available when the webhook is triggered by a schedule run event.

| Variable                     | Type   | Description                                       |
| ---------------------------- | ------ | ------------------------------------------------- |
| `{{scheduleId}}`             | UUID   | Schedule ID                                       |
| `{{schedulerRunId}}`         | UUID   | Scheduler run ID                                  |
| `{{scheduleName}}`           | string | Schedule name                                     |
| `{{scheduleUrl}}`            | URL    | Link to schedule configuration                    |
| `{{failedSuites}}`           | JSON   | Failed suite runs (see structure below)           |
| `{{passedSuites}}`           | JSON   | Passed suite runs (see structure below)           |
| `{{erroredSuites}}`          | JSON   | Errored suite runs (see structure below)          |
| `{{failedSuitesTruncated}}`  | bool   | `true` if failed suites list was truncated to 10  |
| `{{passedSuitesTruncated}}`  | bool   | `true` if passed suites list was truncated to 10  |
| `{{erroredSuitesTruncated}}` | bool   | `true` if errored suites list was truncated to 10 |
| `{{failedTestsCount}}`       | int    | Number of failed tests across all suites          |
| `{{passedTestsCount}}`       | int    | Number of passed tests                            |
| `{{erroredTestsCount}}`      | int    | Number of errored tests                           |
| `{{totalTestsCount}}`        | int    | Total number of tests (including skipped)         |
| `{{failedTests}}`            | JSON   | Failed tests details                              |
| `{{passedTests}}`            | JSON   | Passed tests details                              |
| `{{erroredTests}}`           | JSON   | Errored tests details                             |
| `{{failedTestsTruncated}}`   | bool   | `true` if failed tests list was truncated to 10   |
| `{{passedTestsTruncated}}`   | bool   | `true` if passed tests list was truncated to 10   |
| `{{erroredTestsTruncated}}`  | bool   | `true` if errored tests list was truncated to 10  |

#### JSON Structures

#### `failedTests` / `passedTests` / `erroredTests`

All three lists share the same structure:

```
[
  {
    "testId": "<uuid>",
    "testRunId": "<uuid>",
    "testName": "Login Test",
    "status": "failed",
    "testRunUrl": "https://app.bugbug.io/.../runs-history/tests/<test_run_id>/",
    "started": "2026-03-24T10:00:00+00:00",
    "finished": "2026-03-24T10:05:30+00:00",
    "durationMs": 330500,
    "browser": "Chrome 120.0",
    "browserName": "Chrome",
    "browserVersion": "120.0",
    "os": "Linux",
    "screenSizeType": "desktop",
    "extensionVersion": "1.2.3"
  }
]
```

**Note:** Test lists are limited to 10 entries to prevent oversized payloads.

#### `failedSuites` / `passedSuites` / `erroredSuites`

Available only in schedule run events:

```
[
  {
    "suiteRunId": "<uuid>",
    "suiteRunUrl": "https://app.bugbug.io/.../runs-history/suites/<suite_run_id>/",
    "suiteId": "<uuid>",
    "suiteName": "'MAIN' Suite",
    "status": "failed",
    "started": "2026-03-24T10:00:00+00:00",
    "finished": "2026-03-24T10:05:30+00:00",
    "durationMs": 330500
  }
]
```

{% hint style="warning" %}
**Important:** Use list variables (`failedTests`, `passedTests`, `erroredTests`) **without quotes** in the template to get native JSON arrays in the payload. The template itself won't be valid JSON, but the rendered output will be.
{% endhint %}

{% hint style="warning" %}
**Important:** For numeric and boolean variables (counts, `*Truncated`, etc.) use them **without quotes** to preserve types.
{% endhint %}

#### Example Payloads

These example payloads are also available via the "Fill with example" button in the webapp webhook editor

**Test Run**

```
{
  "id": "{{eventId}}",
  "schemaVersion": "{{schemaVersion}}",
  "eventType": "{{eventName}}",
  "timestampMs": {{timestampMs}},
  "organization": {
    "id": "{{organizationId}}",
    "name": "{{organizationName}}"
  },
  "project": {
    "id": "{{projectId}}",
    "name": "{{projectName}}"
  },
  "test": {
    "id": "{{testId}}",
    "name": "{{testName}}"
  },
  "execution": {
    "id": "{{testRunId}}",
    "status": "{{status}}",
    "started": "{{started}}",
    "finished": "{{finished}}",
    "durationMs": {{durationMs}},
    "triggeredBy": "{{triggeredBy}}",
    "profileName": "{{profileName}}",
    "runMode": "{{runMode}}",
    "browser": "{{browser}}",
    "browserName": "{{browserName}}",
    "browserVersion": "{{browserVersion}}",
    "os": "{{os}}",
    "screenSizeType": "{{screenSizeType}}",
    "extensionVersion": "{{extensionVersion}}"
  },
  "parent": {
    "suiteId": "{{suiteId}}",
    "suiteName": "{{suiteName}}",
    "suiteRunId": "{{suiteRunId}}",
    "scheduleId": "{{scheduleId}}",
    "scheduleName": "{{scheduleName}}",
    "schedulerRunId": "{{schedulerRunId}}"
  },
  "links": {
    "project": "{{projectUrl}}",
    "testRun": "{{testRunUrl}}",
    "test": "{{testUrl}}",
    "suiteRun": "{{suiteRunUrl}}",
    "failedStep": "{{failedStepUrl}}"
  },
  "failedStep": {
    "stepId": "{{failedStepId}}",
    "errorCode": "{{failedStepErrorCode}}"
  }
}
```

**Suite Run**

```
{
  "id": "{{eventId}}",
  "schemaVersion": "{{schemaVersion}}",
  "eventType": "{{eventName}}",
  "timestampMs": {{timestampMs}},
  "organization": {
    "id": "{{organizationId}}",
    "name": "{{organizationName}}"
  },
  "project": {
    "id": "{{projectId}}",
    "name": "{{projectName}}"
  },
  "suite": {
    "id": "{{suiteId}}",
    "name": "{{suiteName}}"
  },
  "execution": {
    "id": "{{suiteRunId}}",
    "status": "{{status}}",
    "started": "{{started}}",
    "finished": "{{finished}}",
    "durationMs": {{durationMs}},
    "triggeredBy": "{{triggeredBy}}",
    "profileName": "{{profileName}}",
    "runMode": "{{runMode}}"
  },
  "parent": {
    "scheduleId": "{{scheduleId}}",
    "scheduleName": "{{scheduleName}}",
    "schedulerRunId": "{{schedulerRunId}}"
  },
  "links": {
    "project": "{{projectUrl}}",
    "suiteRun": "{{suiteRunUrl}}",
    "suite": "{{suiteUrl}}"
  },
  "results": {
    "total": {{totalTestsCount}},
    "counts": {
      "passed": {{passedTestsCount}},
      "failed": {{failedTestsCount}},
      "errored": {{erroredTestsCount}}
    }
  },
  "failedTests": {
    "truncated": {{failedTestsTruncated}},
    "limit": {{objectsLimit}},
    "items": {{failedTests}}
  },
  "passedTests": {
    "truncated": {{passedTestsTruncated}},
    "limit": {{objectsLimit}},
    "items": {{passedTests}}
  },
  "erroredTests": {
    "truncated": {{erroredTestsTruncated}},
    "limit": {{objectsLimit}},
    "items": {{erroredTests}}
  }
}
```

**Schedule Run**

```
{
  "id": "{{eventId}}",
  "schemaVersion": "{{schemaVersion}}",
  "eventType": "{{eventName}}",
  "timestampMs": {{timestampMs}},
  "organization": {
    "id": "{{organizationId}}",
    "name": "{{organizationName}}"
  },
  "project": {
    "id": "{{projectId}}",
    "name": "{{projectName}}"
  },
  "schedule": {
    "id": "{{scheduleId}}",
    "name": "{{scheduleName}}"
  },
  "execution": {
    "id": "{{schedulerRunId}}",
    "status": "{{status}}",
    "started": "{{started}}",
    "finished": "{{finished}}",
    "durationMs": {{durationMs}},
    "profileName": "{{profileName}}",
    "runMode": "{{runMode}}"
  },
  "links": {
    "project": "{{projectUrl}}",
    "schedule": "{{scheduleUrl}}"
  },
  "failedSuites": {
    "truncated": {{failedSuitesTruncated}},
    "limit": {{objectsLimit}},
    "items": {{failedSuites}}
  },
  "passedSuites": {
    "truncated": {{passedSuitesTruncated}},
    "limit": {{objectsLimit}},
    "items": {{passedSuites}}
  },
  "erroredSuites": {
    "truncated": {{erroredSuitesTruncated}},
    "limit": {{objectsLimit}},
    "items": {{erroredSuites}}
  },
  "results": {
    "total": {{totalTestsCount}},
    "counts": {
      "passed": {{passedTestsCount}},
      "failed": {{failedTestsCount}},
      "errored": {{erroredTestsCount}}
    }
  },
  "failedTests": {
    "truncated": {{failedTestsTruncated}},
    "limit": {{objectsLimit}},
    "items": {{failedTests}}
  },
  "passedTests": {
    "truncated": {{passedTestsTruncated}},
    "limit": {{objectsLimit}},
    "items": {{passedTests}}
  },
  "erroredTests": {
    "truncated": {{erroredTestsTruncated}},
    "limit": {{objectsLimit}},
    "items": {{erroredTests}}
  }
}
```


---

# Agent Instructions: 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 current page URL with the `ask` query parameter:

```
GET https://docs.bugbug.io/collaboration/alerts/sending-webhook.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
