# KOI

EvoHub receives alerts from KOI (koi.ai, formerly Koi Security), which watches the extensions, packages, MCP servers and AI agents on your endpoints. KOI sends its alert JSON to a webhook, and EvoHub reads it as it is: an alert opens an EvoHub alert, and the alert being resolved, closed, dismissed or remediated in KOI resolves it.

:::note
**This mapping is provisional.** KOI's webhook payload is not publicly documented, so EvoHub reads it tolerantly: it looks for each value under several field names and keeps every field that arrives on the alert. If your alerts arrive with the wrong title or severity, send us a sample delivery (with any personal data removed) from **Help & Support** and we will map it exactly (see [Get help](https://docs.evohub.io/get-help.md)).
:::

## Set it up

:::steps
### Create the integration
In EvoHub, go to **On-Call → Integrations → + Add Integration**, choose **KOI**, pick an **Escalation Policy** and click **Create Integration**. Copy the **Webhook URL**.
### Add a webhook in KOI
In KOI's integration settings, add a webhook and paste your webhook URL as its address. Choose the alerts to send.

```text
https://evohub.io/ingest/koi?key=YOUR_INTEGRATION_KEY
```
### Send a test
Send a test from KOI, or wait for the next alert. A delivery with no alert in it is answered with `"test": true` and pages nobody; the integration's **Last Event** still updates.
:::

## What EvoHub reads

A delivery may be one alert object, a list of them, or either wrapped in `alerts`, `events`, `data`, `event` or `alert`. For each alert:

| EvoHub alert | Taken from |
| --- | --- |
| Title | `title`, else `name`, `alert_name`, `rule_name`, `policy_name` or `description`; else "KOI alert", followed by the item's name when the alert carries one (`item_name`, `extension_name`, `package_name`, …). |
| Description | `description`, else `message`, `details` or `summary`. |
| Labels | Every field of the alert: nested objects as dotted names (for example `endpoint.hostname`), lists joined with commas. Long values are cut and at most 50 labels are kept. |
| Fingerprint | `id`, else `alert_id`, `event_id` or `uuid`, together with the endpoint when the alert names one (`endpoint_id`, `device_id`, `host_id`, `machine_id`); else the title. |

### Severity

EvoHub reads `severity`, else `risk_level`, `risk` or `priority`, ignoring case:

| KOI value | EvoHub severity |
| --- | --- |
| `critical` | critical |
| `high` | high |
| `medium`, `moderate` | medium |
| `low` | low |
| `info`, `informational` | info |
| anything else, numbers included | medium |

## Resolve and deduplication

- An alert whose `status` is `resolved`, `closed`, `dismissed` or `remediated` resolves the open alert with the same fingerprint. Any other status, such as `open`, `new` or `active`, opens an alert.
- Further deliveries for an alert that is still open are recorded as **Retriggered**.
- Audit events (`source_log_type` `Audit`) are records of changes made in KOI, not alerts: they are answered with `200` and open nothing.

## Troubleshooting

- **`401 INVALID_KEY`**: the URL's key is wrong or the integration is disabled. Copy the **Webhook URL** again from the integration.
- **Alerts are titled "KOI alert"**: KOI sent the alert name under a field EvoHub does not know yet. The alert's labels show every field that arrived; send us the label names, or a sample delivery, so the field can be mapped.
- **Nothing arrives**: check that the webhook in KOI is enabled and selects the alerts you expect.

## Related

- [Integrations overview](https://docs.evohub.io/integrations-overview.md)
- [Cortex XDR](https://docs.evohub.io/cortex-xdr.md)
- [Escalation policies](https://docs.evohub.io/escalation-policies.md)
