# Receive a monitoring tool's webhook

`POST https://evohub.io/ingest/{type}`

Part of the [Alert ingest API](https://docs-dev.evohub.io/alert-ingest.md) reference · operationId `sendIntegrationWebhook`.

The endpoint each integration's webhook URL points at, shown with its
key in On-Call → Integrations. `type` selects the parser.

For `alerts` the body is EvoHub's generic alert (below). For every
other type it is the tool's own webhook payload, sent unchanged — a
firing alert opens an alert, and where the tool reports recovery, the
matching open alert is resolved. Most tools send JSON; UptimeRobot,
StatusCake, Site24x7 and PRTG may send form-encoded data (UptimeRobot
may also append its fields to the URL's query string), and those are
read too.

Answers **200** whenever the payload was read, even if it produced no
alert, so tools do not disable the webhook; `created` and `resolved`
say what happened. An AWS SNS subscription confirmation sent to
`cloudwatch` is confirmed automatically and answered with
`{"data": {"confirmed": true}, "success": true}`.

## Authorization

Requires:

- `integrationKey`

Where:

- `integrationKey`: API key in the query `key` — The integration key (the integration's API Key in On-Call → Integrations).

## Path parameters

- `type` (string, required, one of `alerts`, `prometheus`, `grafana`, `datadog`, `newrelic`, `cloudwatch`, `azuremonitor`, `dynatrace`, `sentry`, `googlecloud`, `zabbix`, `uptimerobot`, `pingdom`, `site24x7`, `statuscake`, `nagios`, `prtg`, `cortex`, `opensearch`, example `alerts`): The integration type.

## Query parameters

- `key` (string, required, example `YOUR_INTEGRATION_KEY`): The integration key.

## Request body (required)

Content type: `application/json`

Type: `GenericAlert | object`

- One of:
  - GenericAlert
    - `title` (string, required, example `Disk almost full on web-03`)
    - `description` (string)
    - `severity` (string, one of `critical`, `high`, `medium`, `low`, `info`, default `medium`)
    - `source` (string, default `webhook`): The alert's source; `webhook` when omitted.
    - `fingerprint` (string): Deduplicates repeated sends while the alert is open.
    - `escalation_policy_id` (string): Used only when the integration has no escalation policy of its own.
    - `labels` (object)
      - Other keys: string
    - `annotations` (object)
      - Other keys: string
  - Native payload: The monitoring tool's own webhook body, for every type except `alerts`.
    - Other keys: any

Content type: `application/x-www-form-urlencoded`

Type: `object`

Form-encoded bodies sent by `uptimerobot`, `statuscake`, `site24x7` and `prtg`.

- Other keys: string

## Responses

### 200 — The payload was read.

Content type: `application/json`

Type: `IngestResult`

- `data` (object)
  - `received` (integer): Alerts and recoveries found in the payload.
  - `created` (integer): Alerts opened, or matched to an alert already open with the same fingerprint.
  - `resolved` (integer): Recoveries processed.
- `success` (boolean, value `true`)

### 400 — The body could not be read as this type's payload (`INVALID_BODY`); for `azuremonitor`, the common alert schema is not enabled (`INVALID_SCHEMA`); for `alerts`, `title` is missing (`VALIDATION_FAILED`, with `details`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `INVALID_KEY`)
  - `message` (string, required, example `invalid integration key`)
  - `details` (array of object): Field problems, on `VALIDATION_FAILED`.
    - `field` (string)
    - `message` (string)

### 401 — `key` is missing, unknown, or names a disabled integration (`INVALID_KEY`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `INVALID_KEY`)
  - `message` (string, required, example `invalid integration key`)
  - `details` (array of object): Field problems, on `VALIDATION_FAILED`.
    - `field` (string)
    - `message` (string)

### 500 — The alert could not be stored (`INTERNAL_ERROR`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `INVALID_KEY`)
  - `message` (string, required, example `invalid integration key`)
  - `details` (array of object): Field problems, on `VALIDATION_FAILED`.
    - `field` (string)
    - `message` (string)

### 503 — The key could not be checked right now (`INGEST_UNAVAILABLE`). Retry after the delay given.

Headers:

- `Retry-After` (integer): Seconds to wait before retrying.

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `INVALID_KEY`)
  - `message` (string, required, example `invalid integration key`)
  - `details` (array of object): Field problems, on `VALIDATION_FAILED`.
    - `field` (string)
    - `message` (string)

## Example request

```bash
curl -X POST 'https://evohub.io/ingest/alerts?key=<INTEGRATION_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
  "title": "Disk almost full on web-03",
  "labels": {
    "host": "web-03.acme.example"
  },
  "source": "cron-disk-check",
  "severity": "high",
  "description": "/var is at 93%",
  "fingerprint": "web-03-disk-var"
}'
```
