Uptimeify Docs

Ausgehende Integrationen

Incident-Management-Ereignisse an Slack, Microsoft Teams, Discord, Jira, PagerDuty, Opsgenie oder einen generischen Webhook weiterleiten, Zustellungen einsehen und erneut senden.

GET /api/im/outbound · POST /api/im/outbound · GET /api/im/outbound/:id · PATCH /api/im/outbound/:id · DELETE /api/im/outbound/:id · GET /api/im/outbound/:id/history · POST /api/im/outbound/:id/retry

Eine ausgehende Integration leitet Incident-Ereignisse (angelegt, bestätigt, Severity oder Status geändert, Kommentar, gelöst) an ein externes System weiter. Anders als ein Kanal, der ein Paging-Ziel einer Eskalation ist, spiegelt eine ausgehende Integration den Lebenszyklus des Incidents in ein anderes Werkzeug. Eine Integration gilt entweder organisationsweit (teamId: null) oder gehört zu einem Team.

Authentifizierung

Erfordert den Basiszugriff auf Incident Management, den jeder Endpunkt dieser API braucht (eine IM-berechtigte Rolle admin, editor oder responder, oder ein organisationsweites API-Token; Incident Management muss für die Organisation aktiviert sein). Lesen (Liste, Detail, Verlauf) darf jede IM-berechtigte Rolle. Anlegen, Ändern, Löschen und erneutes Senden erfordern bei einer organisationsweiten Integration die Rolle admin, bei einer Team-Integration die Rolle admin oder eine Team-Admin-Mitgliedschaft. Ein organisationsweites API-Token läuft mit der Rolle der Person, die es erstellt hat; ein Token, das ein Organisations-Admin erstellt hat, erfüllt diese Hürde also. Eine Team-Admin-Mitgliedschaft gilt für ein Token nie.

Integrationstypen und config

typePflichtfelder in configOptionale Felder in configNur schreibbare Felder
slackwebhookUrlwebhookUrl
teamswebhookUrlwebhookUrl
discordwebhookUrlwebhookUrl
jirabaseUrl (muss mit https:// beginnen), email, apiToken, projectKeyissueType (Standard Task)apiToken
pagerduty_v2routingKeyroutingKey
opsgenieapiKeyregion (us oder eu, Standard eu)apiKey
webhookwebhookUrlbearerToken, headers (Objekt aus Header-Name und Wert)webhookUrl, bearerToken, headers

Nur schreibbare Felder werden verschlüsselt gespeichert und nie zurückgegeben. Jede Antwort setzt sie auf null und ergänzt pro Feld ein Flag: hasWebhookUrl, hasApiToken, hasRoutingKey, hasApiKey, hasBearerToken, und bei webhook zusätzlich hasHeaders (das ganze headers-Objekt kommt als null zurück).

URLs werden beim Speichern nicht auf Erreichbarkeit geprüft. Vom Kunden angegebene Ziele werden beim Senden geprüft: Eine URL, die auf eine private oder lokale Adresse auflöst, lässt die Zustellung scheitern; sie erscheint dann als failed im Zustellverlauf.

Das filters-Objekt

FeldTypBeschreibung
teamsinteger[]Nur Ereignisse von Incidents dieser Team-IDs weiterleiten.
severitiesstring[]Teilmenge von sev1, sev2, sev3, sev4.
event_kindsstring[]Teilmenge von incident_created, acknowledged, severity_changed, status_changed, comment, resolved.

Ein leeres Objekt {} leitet alles weiter. Bei jira wird ein weggelassenes event_kinds zu ["incident_created"], Jira bekommt also ein Ticket pro Incident.

Integrationen auflisten

GET /api/im/outbound

Liefert alle Integrationen deiner Organisation, nach Name sortiert, Geheimnisse geschwärzt.

Beispiel (cURL)

curl -X GET "$BASE_URL/api/im/outbound" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

Antwort (Response)

200 OK

[
  {
    "id": 6,
    "organizationId": 1,
    "teamId": null,
    "type": "pagerduty_v2",
    "name": "PagerDuty bridge",
    "config": { "routingKey": null, "hasRoutingKey": true },
    "filters": { "severities": ["sev1", "sev2"] },
    "isActive": true,
    "createdAt": "2026-09-22T12:00:00.000Z",
    "updatedAt": "2026-09-22T12:00:00.000Z"
  }
]

Integration abrufen

GET /api/im/outbound/:id

Liefert eine Integration, in derselben Form wie ein Listeneintrag.

Integration anlegen

POST /api/im/outbound

Request Body

FeldTypErforderlichBeschreibung
typestringJaEiner der Typen oben. Lässt sich später nicht ändern.
namestringJaGetrimmt, maximal 200 Zeichen.
configobjectJaSiehe Integrationstypen und config.
teamIdinteger | nullNeinTeam deiner Organisation, oder null/weggelassen für eine organisationsweite Integration.
filtersobjectNeinSiehe das filters-Objekt. Standard {}.

Neue Integrationen sind immer aktiv.

Beispiel (cURL)

curl -X POST "$BASE_URL/api/im/outbound" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "jira",
    "name": "Jira OPS",
    "teamId": 3,
    "config": {
      "baseUrl": "https://example.atlassian.net",
      "email": "ops-bot@example.com",
      "apiToken": "ATATT3xFfGF0aB12",
      "projectKey": "OPS"
    }
  }'

Antwort (Response)

200 OK: die angelegte Integration, Geheimnisse geschwärzt.

{
  "id": 7,
  "organizationId": 1,
  "teamId": 3,
  "type": "jira",
  "name": "Jira OPS",
  "config": {
    "baseUrl": "https://example.atlassian.net",
    "email": "ops-bot@example.com",
    "apiToken": null,
    "projectKey": "OPS",
    "hasApiToken": true
  },
  "filters": { "event_kinds": ["incident_created"] },
  "isActive": true,
  "createdAt": "2026-09-22T12:10:00.000Z",
  "updatedAt": "2026-09-22T12:10:00.000Z"
}

Integration ändern

PATCH /api/im/outbound/:id

Teilweise Aktualisierung von name, teamId, filters, config und isActive (Boolean, oder die Strings "true"/"false"). Andere Schlüssel, auch type, werden ignoriert. Du brauchst die Schreibhürde für den aktuellen Geltungsbereich der Integration und, wenn du teamId änderst, auch für den neuen (null macht sie organisationsweit).

  • filters ersetzt die gespeicherten Filter vollständig.
  • config wird mit der gespeicherten Konfiguration zusammengeführt, danach wird das Ergebnis gegen den Typ geprüft. Lass ein nur schreibbares Feld weg oder schick null oder "", um den gespeicherten Wert zu behalten.
  • Bei webhook ersetzt ein mitgeschicktes headers alle gespeicherten Header samt Werten. Lass headers weg, um sie zu behalten.
curl -X PATCH "$BASE_URL/api/im/outbound/7" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "isActive": false }'

200 OK: die aktualisierte Integration, Geheimnisse geschwärzt.

Integration löschen

DELETE /api/im/outbound/:id

Löscht auch den Zustellverlauf der Integration.

curl -X DELETE "$BASE_URL/api/im/outbound/7" \
  -H "Authorization: Bearer $TOKEN"

200 OK

{ "ok": true }

Zustellverlauf

GET /api/im/outbound/:id/history

Zustellversuche einer Integration, neueste zuerst. Zustellungen werden 90 Tage aufbewahrt.

Query-Parameter

ParameterTypBeschreibung
limitintegerSeitengröße, Standard 50, begrenzt auf 1 bis 200.
beforeintegerCursor: liefert Zustellungen mit einer kleineren id. Übergib nextCursor der vorigen Seite.
curl -X GET "$BASE_URL/api/im/outbound/6/history?limit=20" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

200 OK. requestSummary enthält nur den Typ, den Ursprung des Ziels (ohne Pfad) und die Methode; responseSummary enthält den Statuscode und einen gekürzten Body. Keins von beiden enthält Geheimnisse.

{
  "deliveries": [
    {
      "id": 88412,
      "integrationId": 6,
      "incidentId": 42,
      "eventKind": "incident_created",
      "status": "failed",
      "requestSummary": { "type": "pagerduty_v2", "url": "https://events.pagerduty.com", "method": "POST" },
      "responseSummary": { "statusCode": 429, "body": "Rate limit exceeded" },
      "at": "2026-09-22T13:02:11.000Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}

status ist sent, failed oder retrying.

Zustellung erneut senden

POST /api/im/outbound/:id/retry

Stellt einen neuen Sendeauftrag für eine Zustellung dieser Integration in die Warteschlange. Gesendet wird der aktuelle Stand des Incidents (Titel, Severity, Status von jetzt), nicht der ursprüngliche Payload. Der Aufruf kehrt zurück, sobald der Auftrag eingereiht ist; das Ergebnis erscheint als neuer Eintrag im Zustellverlauf.

Begrenzt auf 10 Wiederholungen pro Minute und Integration. Die Grenze zählt jeden berechtigten Aufruf, auch einen, der danach an der Validierung scheitert.

FeldTypErforderlichBeschreibung
deliveryIdintegerJaid einer Zustellung aus dem Verlauf dieser Integration.
curl -X POST "$BASE_URL/api/im/outbound/6/retry" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "deliveryId": 88412 }'

200 OK

{ "ok": true }

Häufige Fehler

  • 401 Unauthorized wenn du nicht authentifiziert bist
  • 403 Forbidden (imAccessDenied) bei Verwendung eines kunden-gescopten Tokens, oder wenn deine Session keine IM-berechtigte Rolle hat
  • 403 Forbidden (imNotEnabled) wenn Incident Management für die Organisation nicht aktiviert ist
  • 403 Forbidden (imOutboundWriteDenied) wenn du eine organisationsweite Integration ohne die Rolle admin schreibst
  • 403 Forbidden (imTeamWriteDenied) wenn du eine Team-Integration ohne die Schreibhürde für dieses Team schreibst
  • 400 Bad Request (invalidRequestBody) wenn :id keine positive Ganzzahl ist, name oder type fehlt oder ungültig ist, ein Pflichtfeld in config fehlt, baseUrl bei jira nicht https nutzt, ein Eintrag in filters ungültig ist, teamId oder isActive ungültig ist, oder deliveryId fehlt
  • 404 Not Found (imOutboundNotFound) wenn die Integration nicht existiert oder zu einer anderen Organisation gehört
  • 404 Not Found (imOutboundDeliveryNotFound) wenn deliveryId keine Zustellung dieser Integration ist
  • 422 Unprocessable Entity (invalidTeamId) wenn teamId nicht zu deiner Organisation gehört
  • 422 Unprocessable Entity (imOutboundNotRetryable) wenn der Typ der Integration nicht erneut gesendet werden kann
  • 429 Too Many Requests (imOutboundRetryRateLimited) wenn die Wiederholungsgrenze erreicht ist. data.retryAfter ist die Wartezeit in Sekunden

Auf dieser Seite