# Send an event

`POST https://evohub.io/ingest/api`

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

Triggers, acknowledges or resolves an alert.

The integration key may be sent as `routing_key` in the body, as
`?key=` in the URL, or as `Authorization: Bearer <key>` — checked in
that order.

A trigger needs only a `summary`; everything else has a default.
Acknowledge and resolve find the open alert by `dedup_key`; when no
open alert has that key, nothing happens and the answer is still 202.
A trigger without a `dedup_key` gets one derived from its summary and
source, returned in the response — keep it to resolve the alert later.
A trigger whose `dedup_key` matches an open alert does not open a
second one; it is recorded as a retrigger on the existing alert.

## Authorization

Any one of:

- `integrationKey`
- `bearerKey`
- No authentication

Where:

- `integrationKey`: API key in the query `key` — The integration key (the integration's API Key in On-Call → Integrations).
- `bearerKey`: HTTP Bearer — The integration key as a bearer token (`/ingest/api` only).

## Query parameters

- `key` (string): The integration key, when it is not sent as `routing_key` or a bearer token.

## Request body (required)

Content type: `application/json`

Type: `EventRequest`

An event. The nested `payload` form and the flat fields are
interchangeable; a flat field fills the payload field it names when
that one is empty (`title` is another name for `summary`).

- `routing_key` (string): The integration key.
- `event_action` (string, one of `trigger`, `acknowledge`, `resolve`, default `trigger`)
- `dedup_key` (string): Identifies the alert. Required for acknowledge and resolve.
- `client` (string): Accepted for Events v2 compatibility; not stored.
- `client_url` (string): Accepted for Events v2 compatibility; not stored.
- `payload` (EventPayload)
  - `summary` (string, example `Database primary is down`): The alert's title. Required for a trigger.
  - `source` (string, example `db-01.prod.acme.example`): Where it happened. Stored as the `source` label.
  - `severity` (Severity, one of `critical`, `high`, `medium`, `low`, `info`, `error`, `warning`, default `medium`)
  - `description` (string)
  - `timestamp` (string (date-time)): Accepted for Events v2 compatibility; the alert is stamped on arrival.
  - `component` (string): Stored as the `component` label.
  - `group` (string): Stored as the `group` label.
  - `class` (string): Stored as the `class` label.
  - `custom_details` (object): Each entry becomes a label, its value as text.
    - Other keys: any
- `summary` (string): Flat form of `payload.summary`.
- `title` (string): Another name for `summary`.
- `severity` (Severity, one of `critical`, `high`, `medium`, `low`, `info`, `error`, `warning`, default `medium`)
- `source` (string): Flat form of `payload.source`.
- `description` (string): The alert's description.

## Responses

### 202 — The event was processed.

Content type: `application/json`

Type: `EventAccepted`

- `data` (object, required)
  - `status` (string, required, value `success`)
  - `message` (string, required, example `Event processed`)
  - `dedup_key` (string, required, example `db-primary-down`): The alert's dedup key — the one sent, or the one derived.
- `success` (boolean, required, value `true`)

### 400 — The body is not JSON, `summary` is missing on a trigger, `dedup_key` is missing on an acknowledge or resolve, or `event_action` is unknown.

Content type: `application/json`

Type: `EventRejected`

How `/ingest/api` answers a request it did not process. The envelope is
the same as for a success (`success` is `true`); read the HTTP status
and `data.status` to tell them apart.

- `data` (object)
  - `status` (string, value `invalid event`)
  - `message` (string, example `summary is required`)
- `success` (boolean)

### 401 — No integration key was sent, or it names no enabled integration.

Content type: `application/json`

Type: `EventRejected`

How `/ingest/api` answers a request it did not process. The envelope is
the same as for a success (`success` is `true`); read the HTTP status
and `data.status` to tell them apart.

- `data` (object)
  - `status` (string, value `invalid event`)
  - `message` (string, example `summary is required`)
- `success` (boolean)

### 500 — The alert could not be created, acknowledged or resolved.

Content type: `application/json`

Type: `EventRejected`

How `/ingest/api` answers a request it did not process. The envelope is
the same as for a success (`success` is `true`); read the HTTP status
and `data.status` to tell them apart.

- `data` (object)
  - `status` (string, value `invalid event`)
  - `message` (string, example `summary is required`)
- `success` (boolean)

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

Headers:

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

Content type: `application/json`

Type: `EventRejected`

How `/ingest/api` answers a request it did not process. The envelope is
the same as for a success (`success` is `true`); read the HTTP status
and `data.status` to tell them apart.

- `data` (object)
  - `status` (string, value `invalid event`)
  - `message` (string, example `summary is required`)
- `success` (boolean)

## Example request

```bash
curl -X POST 'https://evohub.io/ingest/api?key=<INTEGRATION_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
  "summary": "Database primary is down",
  "routing_key": "YOUR_INTEGRATION_KEY"
}'
```
