---
title: "Ingest-Webhook"
description: "Die Ingest-URL je Alarmquelle, an die deine Monitoring-Tools Alarme senden: Authentifizierung, Grenzen und Statuscodes."
---

`POST /api/im/ingest/:token`

Jede Webhook-[Alarmquelle](/de/api/incident-management/alert-sources-api) hat ihre eigene Ingest-URL. Dein Monitoring-Tool sendet sein Alarm-JSON dorthin, und das Mapping der Quelle macht daraus einen Alarm in Incident Management. Die [Einrichtungsanleitungen](/de/api/incident-management/alert-sources) zeigen die Konfiguration für Zabbix, Datadog, Grafana, Prometheus Alertmanager, Sentry und eigene Webhooks.

Um Alarme aus deinem eigenen Code mit einem organisationsweiten API-Token zu senden, nimm stattdessen [Events Ingest](/de/api/incident-management/events-ingest).

## Authentifizierung

Der Token in der URL **ist** die Zugangsberechtigung: Behandle die vollständige URL wie ein Passwort. Sie wird einmal beim Anlegen der Quelle und bei jeder [Rotation](/de/api/incident-management/alert-sources-api) zurückgegeben; nach einer Rotation funktioniert der vorige Token bis `secondaryExpiresAt` weiter.

Eine Quelle kann zusätzlich eines oder beides verlangen:

- **Bearer-Token**: `Authorization: Bearer <Bearer-Token der Quelle>`.
- **HMAC-Signatur**: `X-Uptimeify-Timestamp` (Unix-Sekunden) und `X-Uptimeify-Signature` = HMAC-SHA256 in Hex über `<timestamp>.<roher Body>` mit dem HMAC-Secret der Quelle, optional mit Präfix `sha256=`. Der Zeitstempel darf höchstens 5 Minuten von der Serverzeit abweichen.

Jeder Authentifizierungsfehler, auch ein unbekannter Token, antwortet mit demselben `404`. So lässt sich ein falscher Token nicht von einer falschen Signatur unterscheiden.

## Request

- Body: JSON, höchstens 256 KB, höchstens 20 Ebenen tief verschachtelt. Ein leerer Body gilt als `{}`.
- Der Content-Type wird nicht geprüft; der Body wird als JSON gelesen.
- Welche Felder zählen, bestimmt das Mapping der Quelle (Vorlage oder eigenes). Der Body unten passt zu einer eigenen Webhook-Quelle, die auf diese Feldnamen gemappt ist.

### Beispiel (cURL)

```bash
curl -X POST "https://uptimeify.io/api/im/ingest/$INGEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title":"Disk almost full on db-1","severity":"high","status":"firing","dedup_key":"db-1-disk"}'
```

Mit HMAC:

```bash
TS=$(date +%s)
BODY='{"title":"Disk almost full on db-1","status":"firing"}'
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex | sed 's/^.* //')
curl -X POST "https://uptimeify.io/api/im/ingest/$INGEST_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Uptimeify-Timestamp: $TS" \
  -H "X-Uptimeify-Signature: sha256=$SIG" \
  -d "$BODY"
```

## Antwort (Response)

`202 Accepted`:

```json
{ "accepted": true }
```

Der Payload ist zur Verarbeitung angenommen; Mapping, Deduplizierung und Alarmierung laufen asynchron. Was daraus wurde, zeigen [Statistik und letzte Payloads](/de/api/incident-management/alert-sources-api) der Quelle.

## Grenzen

- 300 Requests pro Minute und Quelle
- 50 MB Request-Bodies pro Stunde und Organisation

## Statuscodes

| Status | Body | Bedeutung |
|--------|------|-----------|
| `202` | `{"accepted":true}` | Angenommen. |
| `404` | `{"error":"not_found"}` | Unbekannter oder abgelaufener Token, fehlgeschlagene Bearer- oder HMAC-Prüfung, oder die Organisation wurde gelöscht. |
| `413` | `{"error":"payload_too_large"}` | Body größer als 256 KB. |
| `422` | `{"error":"invalid_json"}` | Body ist kein gültiges JSON. |
| `422` | `{"error":"payload_too_deep"}` | JSON tiefer als 20 Ebenen verschachtelt. |
| `429` | `data.code` `imIngestRateLimited` | Mehr als 300 Requests pro Minute für diese Quelle. |
| `429` | `data.code` `imIngestByteBudgetExceeded` | Stündliches Byte-Budget der Organisation aufgebraucht. |
| `503` | `{"error":"unavailable"}` | Vorübergehend nicht annahmebereit; mit Backoff wiederholen. Die eingebaute Wiederholung deines Tools ist die richtige Antwort. |
