Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,96 @@ Failed Response:
}
```

## III. Best Practices <span id="best-practices"></span>
## III. Field Mapping and Value Mapping
---

If your system's JSON format cannot directly match the standard Payload structure above, you can configure **field mapping** and **value mapping** in the integration settings to let Flashduty automatically convert any JSON format into standard alert events.

###### Once field mapping is configured, the request body no longer requires a fixed format. It accepts any JSON object, and also supports batch push via JSON arrays (up to 100 items per request).


### Field mapping

Use `{{variable.path}}` syntax to reference fields from the original JSON and map them to target fields of the standard alert event.

Supported target fields:

| Target field | Description |
| :--- | :--- |
| title | Alert title |
| title_rule | Alert title rule |
| description | Alert description |
| event_status | Alert status (Critical / Warning / Info / Ok) |
| alert_key | Alert identifier |
| labels | Alert labels |
| images | Image array |

**Variable syntax:**

- Use `.` to separate path levels, e.g. `{{data.severity}}` references a nested field
- When the entire value is a single variable (e.g. `"{{tags}}"`), the original data type is preserved (object, array, etc.)
- When a variable is mixed with other text (e.g. `"{{host}} - {{check}}"`), variables are converted to strings for concatenation

**Two ways to map labels:**

- **Wildcard expansion**: `"labels": "{{tags}}"` — expands all children of the `tags` object as labels
- **Per-label mapping**: `"labels": {"env": "{{tags.env}}", "host": "{{hostname}}"}` — maps each label individually

**Example:**

Your system pushes the following format:

```json
{
"alert_name": "CPU usage high",
"status": "firing",
"severity": "high",
"host": "web-01",
"tags": {
"env": "production",
"service": "api"
}
}
```

Configure the following field mapping:

```json
{
"title_rule": "{{alert_name}}",
"event_status": "{{severity}}",
"alert_key": "{{host}}::{{alert_name}}",
"description": "Host {{host}} alert: {{alert_name}}",
"labels": "{{tags}}"
}
```

### Value mapping

When your source system's field values differ from Flashduty's standard (e.g. using `high` instead of `Critical` for severity), configure value mapping for automatic conversion.

Value mapping is configured per **field path**, with each path containing a `source value → target value` mapping table.

**Example:**

```json
{
"severity": {
"high": "Critical",
"medium": "Warning",
"low": "Info",
"resolved": "Ok"
}
}
```

Combined with the field mapping above, `"severity": "high"` in the original JSON is first extracted via field mapping, then converted to `Critical` via value mapping, and finally written to the `event_status` field.


###### Warning: All `{{...}}` variables must resolve to a value in the original JSON, otherwise the request will fail. It is recommended to test your mapping configuration with a small dataset first.


## IV. Best Practices <span id="best-practices"></span>
---

1. Send events to Flashduty when alert status changes
Expand All @@ -187,7 +276,7 @@ Failed Response:
- Alert ownership information, like team, owner
- Alert category information, like class (api, db, net)

## IV. FAQ
## V. FAQ
---

<details>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ Configure the parameters Flashduty uses when making requests to your endpoint:
| **Method** | No | Request method, `GET` or `POST`. Defaults to `GET`. Body cannot be set when using GET |
| **Headers** | No | Custom request headers in key-value format. For security reasons, sensitive headers such as `Authorization` and `Cookie` are not allowed |
| **Body** | No | Request body, only available for POST. Supports [template variables](#template-variables) and must be valid JSON |
| **Timeout** | No | Per-request timeout, 1–10 seconds. Defaults to 5 seconds |
| **RetryCount** | No | Number of retries on failure, 0–2. Defaults to 1 |
| **Timeout** | No | Per-request timeout, 1–300 seconds. Defaults to 10 seconds |
| **RetryCount** | No | Number of retries on failure, 0–10. Defaults to 0 |

</div>

Expand Down Expand Up @@ -155,7 +155,8 @@ URL and Body support Go `text/template` syntax. The following variables are avai
| `{{.NowTime}}` | int64 | Current time (Unix timestamp in seconds) |
| `{{.LastPullTimeISO}}` | string | Last pull time (ISO 8601 format, e.g., `2026-05-13T06:00:00Z`) |
| `{{.NowTimeISO}}` | string | Current time (ISO 8601 format) |
| `{{.CursorValue}}` | string | Pagination cursor value, empty for the first page |
| `{{.CursorValue}}` | string | Pagination cursor value, empty for the first page. Equivalent to `{{.PageValue}}` |
|| `{{.PageValue}}` | string | Alias for the pagination cursor value, equivalent to `{{.CursorValue}}`. Empty string on the first request; subsequent requests use the value extracted from the previous response via the cursor path |

### Examples

Expand Down Expand Up @@ -232,7 +233,18 @@ Values that do not match any mapping are processed as-is.

</div>

## VI. FAQ
## VI. Default Route
---

<div class="md-block">

When creating a "Shared Integration" (under **Integration Center => Alert Events**), you must configure a default route — otherwise newly pulled events will be dropped. After creation, you can add finer-grained rules under **Route**.

A "Dedicated Integration" (created under the **Integrations** tab of a specific channel) is automatically bound to that channel and does not need a separate default route.

</div>

## VII. FAQ
---

<details>
Expand Down Expand Up @@ -261,7 +273,6 @@ Values that do not match any mapping are processed as-is.
3. If you use `alert_key`, check whether the alert is a duplicate — events with identical status and content are deduplicated and discarded.
4. Check if any drop rules, inhibit rules, or silence rules are matching.

For more information, see [Noise reduction](/en/on-call/channel/noise-reduction).

</details>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,84 @@ curl -X POST 'https://example.com/incident/webhook?a=a' \
}' -v
```

## III. FAQ
## III. Custom Request Body and Value Mapping

### Custom request body

By default, the system pushes the complete JSON data following the Payload structure described above. If your receiver requires a specific data format, you can use a **custom request body** to reorganize the push content.

Use `{{field.path}}` syntax to reference any field from the default Payload. The system replaces variables with actual values at push time.

**Variable syntax:**

- Use `.` to separate path levels, e.g. `{{incident.title}}` references the incident title
- Array index access is supported, e.g. `{{incident.responders.0.email}}` references the first responder's email
- When the entire value is a single variable (e.g. `"{{incident.labels}}"`), the original data type is preserved (object, array, number, etc.)
- When a variable is mixed with other text (e.g. `"Incident: {{incident.title}}"`), the variable is converted to a string for concatenation

**Example:**

Transform the default Payload into a custom format for an internal system:

```json
{
"msg_type": "incident",
"event": "{{event_type}}",
"content": {
"id": "{{incident.incident_id}}",
"name": "{{incident.title}}",
"severity": "{{incident.incident_severity}}",
"status": "{{incident.progress}}",
"channel": "{{incident.channel_name}}",
"url": "{{incident.detail_url}}",
"labels": "{{incident.labels}}",
"responders": "{{incident.responders}}"
}
}
```

:::tips
If a variable path does not exist in the default Payload, the system keeps the original `{{...}}` text without replacement. It is recommended to first check the actual default Payload via invocation history to confirm available field paths.
:::

### Value mapping

In the custom request body, you may need to convert Flashduty field values to the format expected by the receiving system. **Value mapping** automatically transforms values during variable resolution.

Value mapping is configured per **field path**, with each path containing a `source value → target value` mapping table.

**Example:**

Convert severity and progress to custom values for the receiving system:

```json
{
"incident.incident_severity": {
"Critical": "P0",
"Warning": "P1",
"Info": "P2"
},
"incident.progress": {
"Triggered": "open",
"Processing": "in_progress",
"Closed": "resolved"
}
}
```

Used with the following custom request body:

```json
{
"severity": "{{incident.incident_severity}}",
"status": "{{incident.progress}}",
"title": "{{incident.title}}"
}
```

When the incident severity is `Critical`, the `severity` field in the push result will be `P0`. Values that do not match any mapping are sent as-is.

## IV. FAQ

1. **Is there a response timeout for the service?**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,58 @@ curl -X POST 'https://example.com/incident/action?a=a' \
}' -v
```

## III. Use Cases
## III. Custom Request Body and Value Mapping

### Custom request body

By default, the system pushes the complete JSON data following the Payload structure described above. If your receiver requires a specific data format, you can use a **custom request body** to reorganize the push content.

Use `{{field.path}}` syntax to reference any field from the default Payload. The system replaces variables with actual values at push time.

**Variable syntax:**

- Use `.` to separate path levels, e.g. `{{incident.title}}` references the incident title
- Array index access is supported, e.g. `{{incident.responders.0.email}}` references the first responder's email
- When the entire value is a single variable (e.g. `"{{incident.labels}}"`), the original data type is preserved (object, array, number, etc.)
- When a variable is mixed with other text (e.g. `"Incident: {{incident.title}}"`), the variable is converted to a string for concatenation

**Example:**

```json
{
"action": "{{event_type}}",
"incident_id": "{{incident.incident_id}}",
"title": "{{incident.title}}",
"severity": "{{incident.incident_severity}}",
"url": "{{incident.detail_url}}",
"operator": "{{person.person_name}}",
"labels": "{{incident.labels}}"
}
```

:::tips
If a variable path does not exist in the default Payload, the system keeps the original `{{...}}` text without replacement. It is recommended to first check the actual default Payload via a test push to confirm available field paths.
:::

### Value mapping

Value mapping automatically transforms field values during variable resolution in the custom request body. Value mapping is configured per **field path**.

**Example:**

```json
{
"incident.incident_severity": {
"Critical": "P0",
"Warning": "P1",
"Info": "P2"
}
}
```

Used with `"severity": "{{incident.incident_severity}}"` in the custom request body, when the incident severity is `Critical`, the `severity` field in the push result will be `P0`. Values that do not match any mapping are sent as-is.

## IV. Use Cases

### Host Restart

Expand Down
Loading