> ## Documentation Index
> Fetch the complete documentation index at: https://test-8ad8522e-feat-doc-review-auto-fix.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Change Events

> Push change events from your own systems to Flashduty On-call via standard protocol. Most incidents are caused by changes, and linking changes with alert events helps quickly identify incident root causes

<Tip>**Plan requirement**: This feature requires an On-call Standard or higher subscription. [Learn more](https://flashcat.cloud/flashduty/price/)</Tip>

<Tip>
  Flashduty On-call has adapted webhook protocols for some common ticketing and deployment systems. For these systems, you should first use the corresponding integrations. This integration provides a standard HTTP interface that requires your development adaptation, with the benefit of integrating with any deployment system.
</Tip>

## Steps

<Steps>
  <Step title="Enter Integration Center">
    Go to Flashduty console, select **Integration Center => Change Events** to enter the integration selection page.
  </Step>

  <Step title="Create Integration">
    Select **Custom Event** integration and define a name for the current integration.
  </Step>

  <Step title="Get Push URL">
    Click **Save**, then copy the newly generated **Push URL** from the current page for later use.
  </Step>
</Steps>

## Implement Protocol

### Request description

Request method:

```http theme={null}
POST, Content-Type: application/json
```

Use the **push URL** shown on the integration details page. The URL format is:

```text theme={null}
{api_host}/event/push/change/standard?integration_key={integration_key}
```

### Request parameters

#### Headers

| Field        | Required | Type   | Description                      |
| :----------- | :------: | :----- | :------------------------------- |
| Content-Type |    Yes   | string | Fixed value: `application/json`. |

#### Query strings

| Field            | Required | Type   | Description                                                                                                  |
| :--------------- | :------: | :----- | :----------------------------------------------------------------------------------------------------------- |
| integration\_key |    Yes   | string | Integration secret used for access control. You can get it from the push URL after creating the integration. |

#### Payload

| Field          | Required | Type    | Description                                                                                                                                                                                                                          |
| :------------- | :------: | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| title          |    Yes   | string  | Change title, such as a release title, ticket title, or deployment task name.                                                                                                                                                        |
| change\_key    |    Yes   | string  | Change identifier. Events with the same `change_key` are treated as the same change. Subsequent events update the change status, labels, and link.                                                                                   |
| change\_status |    Yes   | string  | Change status. Enum values are case-sensitive: `Planned`, `Ready`, `Processing`, `Canceled`, and `Done`.                                                                                                                             |
| event\_time    |    No    | integer | Event occurrence time as a Unix timestamp. Seconds and milliseconds are both supported. If omitted, Flashduty uses the time when the event is received.                                                                              |
| description    |    No    | string  | Change description, such as change content, impact scope, execution steps, or rollback plan.                                                                                                                                         |
| link           |    No    | string  | Change details link, such as a release, ticket, or CI/CD task URL.                                                                                                                                                                   |
| labels         |    No    | map     | Change labels. Both keys and values must be strings. We recommend following the Prometheus label naming convention for keys. Flashduty replaces special characters such as spaces, dots, and slashes in label keys with underscores. |

<Note>
  When `change_status` is `Done` or `Canceled`, Flashduty records the event time as the change end time. If you report a non-terminal status again, the end time is cleared.
</Note>

### Response

| Field       | Required | Type            | Description                                        |
| :---------- | :------: | :-------------- | :------------------------------------------------- |
| request\_id |    Yes   | string          | Request ID for tracing.                            |
| error       |    No    | [Error](#error) | Error details. Returned only when an error occurs. |
| data        |    No    | object          | Empty object returned after a successful report.   |

#### Error <span id="error" />

| Field   | Required | Type   | Description                    |
| :------ | :------: | :----- | :----------------------------- |
| code    |    Yes   | string | Error code. See [Code](#code). |
| message |    No    | string | Error message.                 |

#### Code <span id="code" />

| Error code           | HTTP status | Description                                                                                                    |
| :------------------- | :---------: | :------------------------------------------------------------------------------------------------------------- |
| InvalidParameter     |     400     | Invalid parameter, such as a missing required field, invalid status enum value, or invalid integration secret. |
| InvalidContentType   |     400     | Unsupported `Content-Type`.                                                                                    |
| MethodNotAllowed     |     405     | Unsupported HTTP method.                                                                                       |
| Unauthorized         |     401     | Authentication failed.                                                                                         |
| AccessDenied         |     403     | Permission check failed.                                                                                       |
| RequestTooFrequently |     429     | Requests are too frequent.                                                                                     |
| RouteNotFound        |     404     | Request method and path do not match any route.                                                                |
| ResourceNotFound     |     400     | The account has not purchased the resource. Go to Billing to place an order first.                             |
| NoLicense            |     400     | The account does not have enough plan licenses. Upgrade or purchase a plan first.                              |
| InternalError        |     500     | Internal or unknown error.                                                                                     |

### Request example

Request:

```bash theme={null}
curl -X POST '{api_host}/event/push/change/standard?integration_key={integration_key}' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "order-service v1.12.0 production release",
    "change_key": "deploy-order-service-202607231030",
    "change_status": "Processing",
    "event_time": 1784773800,
    "description": "Deploy order-service v1.12.0 to production cluster cn-shanghai-prod.",
    "link": "https://deploy.example.com/releases/deploy-order-service-202607231030",
    "labels": {
      "service": "order-service",
      "env": "prod",
      "cluster": "cn-shanghai-prod",
      "owner": "sre"
    }
  }' -v
```

Successful response:

```json theme={null}
{
  "request_id": "0ace00116215ab4ca0ec5244b8fc54b0",
  "data": {}
}
```

Failed response:

```json theme={null}
{
  "request_id": "0ace00116215abc0ba4e52449bd305b0",
  "error": {
    "code": "InvalidParameter",
    "message": "Key: 'ChangeEvent.ChangeStatus' Error:Field validation for 'ChangeStatus' failed on the 'oneof' tag"
  }
}
```

## Best Practices

Labels describe events and should be as rich as possible:

* **Change scope**: such as host, cluster, etc.
* **Change ownership**: such as team, owner, etc.
* **Change lifecycle**: use the same `change_key` to report different `change_status` values as the change moves through planned, processing, completed, or canceled states. This helps restore the change process on the incident timeline.

## FAQ

<AccordionGroup>
  <Accordion title="Why didn't Flashduty receive the change?">
    **Troubleshoot in Flashduty On-call**

    Check if the integration shows **Latest Event Time**. If not, Flashduty hasn't received the push—prioritize troubleshooting your system.

    **Troubleshoot in Your System**

    1. Confirm the request URL matches exactly with the URL in integration details
    2. Confirm your service can access the external `api.flashcat.cloud` domain. If not, you need to enable external network access for the server, or specifically enable external access for Flashduty On-call's domain
    3. Print Flashduty service response to check for specific error messages

    If the root cause is still not found after the above steps, please contact us **with the request\_id from the response**.
  </Accordion>
</AccordionGroup>
