> ## Documentation Index
> Fetch the complete documentation index at: https://docs.incident.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Declare incidents automatically from other tools

> Turn signals from your monitoring, ticketing, and internal tools into incidents, without anyone declaring them by hand.

There are two ways to declare incidents from another tool: send its events to an [HTTP alert source](#send-alerts-to-an-alert-source), or call the [create incident API](#call-the-create-incident-api). Choose based on who has already decided that something is an incident:

* **Use an alert source** when the tool reports a signal that might be an incident: a monitor firing, an error rate climbing, a check failing. incident.io deduplicates repeated events, groups related alerts into one incident, pages the right people, and can decline the incident when the signal clears.
* **Use the API** when someone or something has already decided it's an incident: a support agent clicking **Escalate** in your ticketing tool, a form in an internal portal, or a script that runs your own logic. You get an incident straight away, with the fields you set.

If your tool is on the list of [supported alert sources](/alerts/alert-sources), start there: you get the alert source behavior without building anything.

## Send alerts to an alert source

[Create an HTTP alert source](https://app.incident.io/~/on-call/alert-routes/sources/create?source_type=http). It gives you a URL and a secret token to send events to:

```bash theme={null}
curl --request POST 'https://api.incident.io/v2/alert_events/http/<ALERT_SOURCE_ID>' \
  --header 'Authorization: Bearer <ALERT_SOURCE_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "title": "Checkout error rate above 5%",
    "status": "firing",
    "deduplication_key": "checkout-error-rate",
    "description": "5xx rate has been above 5% for 2 minutes.",
    "source_url": "https://monitoring.example.com/alerts/123",
    "metadata": { "service": "checkout", "team": "payments" }
  }'
```

If you can't change the shape of what your tool sends, use a [custom HTTP source](/alerts/custom-http-sources) with a transform expression instead. See the [alert events API](/api-reference/alert-events-v2) for every field.

### How events become alerts

The `deduplication_key` identifies the thing you're alerting on:

* **Repeat events update the alert.** Sending `firing` again with the same key updates the existing alert rather than creating a new one, so a monitor that re-sends every minute produces one alert.
* **`resolved` resolves it.** Send the same key with `"status": "resolved"` when the signal clears.
* **Firing again after that starts a new alert**, because the previous one is resolved.

Use `metadata` to set [alert attributes](/on-call/alert-attributes), like the affected service or team, so you can route and filter on them. Each alert source has its own [rate limit](/alerts/rate-limits).

### How alerts become incidents

An [alert route](/on-call/alert-routing) connects the alert source to incidents and paging. For each route, you choose:

* **Which alerts count**, by filtering on alert attributes and priority.
* **Whether related alerts share an incident**, by grouping alerts that fire close together, or that share attributes like the service.
* **Whether incidents start in triage.** Triage incidents let a responder accept or decline before the incident process starts. Tick **Decline triage incidents if the linked alerts are resolved** to decline them automatically when the signal clears.
* **Who gets paged**, through escalation paths. Paging and incident creation are independent, so a route can page without creating incidents, or the reverse.
* **How the incident looks**: its name, summary, severity, and custom fields, set from the alert. See [Incident templates](/alerts/incident-templates).

Declining or resolving the incident resolves its alerts. During a [maintenance window](/alerts/maintenance-windows), matching alerts skip their alert routes, and the window decides what happens to them instead.

## Call the create incident API

Create an [API key](/admin/api-keys) with the **Create incidents** permission, and call the [create incident endpoint](/api-reference/incidents-v2/create):

```bash theme={null}
curl --request POST 'https://api.incident.io/v2/incidents' \
  --header 'Authorization: Bearer <YOUR_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "idempotency_key": "zendesk-ticket-48213",
    "visibility": "public",
    "name": "Customers can't complete checkout",
    "severity_id": "<SEVERITY_ID>"
  }'
```

* **Use an ID from your tool as the `idempotency_key`**, like the ticket number. Sending the same key again returns the incident you already created, so retries never make duplicates.
* **The incident starts in an active status** and opens its own Slack or Microsoft Teams channel, unless its incident type is set to start in triage or to skip creating a channel. A `severity_id` is required for an active incident. List yours with the [severities endpoint](/api-reference/severities-v1/list).
* **Set anything a responder would**: the incident type, custom fields, role assignments, and timestamps. See [Creating your first incident using the API](/integrations/api-create-incident) for a walkthrough.
* **Run workflows on API-created incidents** by adding a condition on the **API Key creator**, so you can, for example, invite the support agent who escalated the ticket.

Creating incidents through the API has its own [rate limit](/api-reference/introduction#rate-limits), which is lower for incidents that open a new channel. If a tool might send you a burst, like a monitor, use an alert source instead.

## Page someone without an incident

To page a team without declaring an incident, create an [escalation](/api-reference/escalations-v2/create) through the API, or use an alert route that escalates without creating incidents.
