Webhook für das Changelog abonnieren

POST https://api.keenauth.com/v1/accounts/{account_id}/changelog-subscriptions · Kontoinhaber oder Administrator

Registriert einen eigenen HTTPS-Endpunkt, der einen changelog.entry_published-Webhook empfängt, sobald ein Changelog-Eintrag in einer der gewählten Kategorien veröffentlicht wird. Die Anfrage wird mit den Zugangsdaten von keenauth login gestellt: Das Konto muss dasjenige sein, bei dem Sie angemeldet sind, und Sie müssen dessen Inhaber oder Administrator sein. Ein Konto kann höchstens 5 aktivierte Abonnements haben.

Jedes Abonnement hat ein eigenes Signaturgeheimnis, das in der Antwort einmalig zurückgegeben wird. Die Zustellung folgt Standard Webhooks: Jede Anfrage enthält die Header webhook-id, webhook-timestamp und webhook-signature, und die Signatur (v1,<base64>) ist ein HMAC-SHA256 über <webhook-id>.<webhook-timestamp>.<body>. Der HMAC-Schlüssel sind die 32 Bytes, die die 43 Zeichen nach dem Präfix idp_whsec_ kodieren (Base62, Big-Endian); die letzten 6 Zeichen sind eine Prüfsumme und gehören nicht zum Schlüssel. Prüfen Sie die Signatur und lehnen Sie einen Zeitstempel ab, der zu weit von der aktuellen Zeit entfernt ist (die Standard-Webhooks-Bibliotheken erlauben 5 Minuten), bevor Sie dem Inhalt vertrauen.

Legen Sie keine personenbezogenen Daten, Zugangsdaten oder Token in die URL: Sie wird mit dem Abonnement gespeichert und allen Inhabern und Administratoren des Kontos angezeigt.

Anfrage

Header:

Header Pflicht Beschreibung
Authorization ja DPoP <access token>: das Zugriffstoken, das die CLI beim Anmelden erhalten hat.
DPoP ja Ein DPoP-Nachweis für diese Anfrage (htm POST, htu die URL dieser Anfrage), signiert mit dem Schlüssel, an den das Zugriffstoken gebunden ist; er enthält den Hash des Zugriffstokens und den Server-Nonce.
Content-Type ja application/json.
Idempotency-Key nein 16 bis 64 Zeichen aus A-Z, a-z, 0-9, _ und -. Wiederholt man die Anfrage mit demselben Schlüssel und Inhalt innerhalb von 24 Stunden, wird dasselbe Abonnement ohne das Geheimnis zurückgegeben, mit secret_redacted: true und dem Header Idempotent-Replayed: true.

Anfragetext:

Feld Pflicht Beschreibung
url ja Der Endpunkt: https, Port 443, ein Hostname (keine IP-Adresse und kein nur lokal gültiger Name wie .localhost, .local oder .internal), ohne Benutzerinformationen oder Fragment, höchstens 2048 Byte.
categories nein Beliebige der Werte api, sdk, deprecation, security und incident, jeweils höchstens einmal. Lassen Sie das Feld weg, um alle Kategorien zu erhalten; ein leeres Array wird abgelehnt.

Antwort

201 Created mit Cache-Control: no-store:

Feld Beschreibung
id Das Abonnement (chlg_…).
account_id Das Konto (acct_…).
url Der Endpunkt.
categories Die empfangenen Kategorien in der Reihenfolge api, sdk, deprecation, security, incident.
status enabled, oder disabled, wenn Zustellungen wiederholt fehlschlagen.
created_at Zeitpunkt der Erstellung des Abonnements (RFC 3339, UTC).
signing_secret Das Signaturgeheimnis (idp_whsec_…). Wird nur in dieser Antwort zurückgegeben; speichern Sie es in Ihrem Secret-Manager.
secret_redacted true bei einer idempotenten Wiederholung, die kein signing_secret enthält.

Fehler

Status Code Wann
400 malformed_request Der Anfragetext ist kein JSON, oder der Header Idempotency-Key ist mehrfach vorhanden, leer oder fehlerhaft.
400 unknown_field Der Anfragetext enthält ein anderes Feld als url und categories.
401 unauthenticated Es wurde kein Zugriffstoken gesendet.
401 invalid_token Das Zugriffstoken ist ungültig, abgelaufen oder gehört nicht zur CLI; melden Sie sich erneut mit keenauth login an.
401 invalid_dpop_proof Der DPoP-Nachweis fehlt, ist mehrfach vorhanden oder passt weder zur Anfrage noch zum Schlüssel des Tokens.
401 use_dpop_nonce Wiederholen Sie die Anfrage mit einem Nachweis, der den Nonce aus dem Antwortheader DPoP-Nonce enthält.
401 insufficient_user_authentication Multi-Faktor-Authentifizierung (bzw. für Inhaber und Administratoren ein Passkey oder Sicherheitsschlüssel) ist erforderlich; melden Sie sich erneut an.
403 insufficient_permissions Sie sind kein Inhaber und kein Administrator des Kontos.
403 account_restricted Der Status des Kontos erlaubt keine Änderungen.
403 quota_exceeded Das Konto hat bereits 5 aktivierte Abonnements (errors[].code changelog_subscription_limit_exceeded).
404 not_found Das Konto existiert nicht, ist nicht das Konto, bei dem Sie angemeldet sind, oder Sie sind dort kein Mitglied.
413 payload_too_large Der Anfragetext ist größer als 8 KiB.
415 unsupported_media_type Der Anfragetext ist nicht application/json.
422 validation_failed url fehlt oder ist ungültig, eine Kategorie ist unbekannt oder mehrfach angegeben, categories ist leer, oder ein Feld hat den falschen Typ.
422 idempotency_key_reuse Der Idempotency-Key wurde innerhalb von 24 Stunden mit einem anderen Anfragetext verwendet.
429 rate_limited In der letzten Stunde wurden für das Konto mehr als 10 Abonnements erstellt; warten Sie Retry-After ab.

Webhook-Zustellung

Wenn ein Eintrag veröffentlicht wird, sendet KeenAuth einen POST an die URL jedes aktivierten Abonnements, dessen Kategorien eine der Kategorien des Eintrags enthalten. Derselbe Eintrag wird einem Abonnement nie zweimal gesendet.

Anfrage

Header Beschreibung
Content-Type application/json.
webhook-id Die Ereigniskennung id (evt_…). Sie ist bei jeder Wiederholung desselben Eintrags gleich, verwenden Sie sie daher, um Duplikate zu ignorieren.
webhook-timestamp Unix-Zeit in Sekunden, zu der dieser Versuch signiert wurde. Sie ist bei jedem Versuch neu.
webhook-signature v1,<base64>: der oben beschriebene HMAC-SHA256 über <webhook-id>.<webhook-timestamp>.<body>.

Der Anfragetext ist höchstens 16 KiB groß. KeenAuth folgt keinen Weiterleitungen.

Ereignis

{
  "id": "evt_01jb0000000000000000000000",
  "type": "changelog.entry_published",
  "schema_version": 1,
  "occurred_at": "2026-11-04T00:00:00Z",
  "recorded_at": "2026-11-04T08:30:12Z",
  "data": {
    "id": "2026-11-04-example",
    "url": "https://docs.keenauth.com/en/changelog/#2026-11-04-example",
    "title": "Example entry",
    "date_published": "2026-11-04T00:00:00Z",
    "tags": ["deprecation"],
    "categories": ["api", "deprecation"],
    "surfaces": [{"kind": "api", "name": "management-v1", "version": "v1"}],
    "breaking": false,
    "sunset_at": "2027-11-04"
  }
}
Feld Beschreibung
id Das Ereignis (evt_…), identisch mit dem Header webhook-id.
type Immer changelog.entry_published.
schema_version Immer 1. Innerhalb von Version 1 können data neue optionale Felder hinzugefügt werden; ignorieren Sie unbekannte Felder.
occurred_at Zeitpunkt der Veröffentlichung des Eintrags (RFC 3339).
recorded_at Zeitpunkt, zu dem KeenAuth die Zustellung eingereiht hat (RFC 3339).
data.id, data.url, data.title, data.date_published Der Eintrag, wie in den Changelog-Feeds.
data.tags Ein oder mehrere der Werte added, changed, fixed, removed, deprecation, security, breaking und incident.
data.categories Die Abonnement-Kategorien, zu denen der Eintrag gehört.
data.surfaces Die betroffenen Oberflächen: kind (api, sdk, cli, provider, mcp oder docs), name und, sofern bekannt, version.
data.breaking true, wenn die Änderung inkompatibel ist.
data.sunset_at Das Entfernungsdatum einer Veralterung (YYYY-MM-DD), andernfalls null.

Das maschinenlesbare Schema ist changelog.entry_published.v1.

Antworten und Wiederholungen

Antworten Sie innerhalb von 15 Sekunden mit einem beliebigen 2xx-Status. Der Antworttext wird ignoriert. Jedes andere Ergebnis ist ein fehlgeschlagener Versuch und wird wiederholt: ein Verbindungs- oder TLS-Fehler, ein Timeout, eine Weiterleitung, 429, 5xx und jeder andere Status außer 410. Der erste Versuch erfolgt sofort; die folgenden etwa 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden, 8 Stunden, 24 Stunden und 36 Stunden nach dem vorherigen Fehlschlag (jedes Intervall variiert um bis zu 10 Prozent), insgesamt 8 Versuche in etwa 3 Tagen.

Schlägt der achte Versuch fehl, wird die Zustellung aufgegeben und das Abonnement deaktiviert (status disabled). Bereits für das Abonnement eingereihte Zustellungen werden abgebrochen.

410 Gone

Antworten Sie mit 410 Gone, um KeenAuth mitzuteilen, dass Sie keine Zustellungen mehr wünschen. Das Abonnement wird sofort ohne weitere Versuche deaktiviert, und seine eingereihten Zustellungen werden abgebrochen. Ein deaktiviertes Abonnement wird nicht wieder aktiviert und zählt nicht zum Limit von 5; erstellen Sie ein neues, um wieder Einträge zu erhalten. Jede Deaktivierung wird im Audit-Log des Kontos als changelog.subscription_disabled festgehalten, mit dem Grund receiver_gone, permanent_failure oder schedule_exhausted.

Beispiel

curl -X POST https://api.keenauth.com/v1/accounts/acct_01jb0000000000000000000000/changelog-subscriptions \
  -H "Authorization: DPoP $ACCESS_TOKEN" \
  -H "DPoP: $DPOP_PROOF" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: changelog-hooks-2026-10" \
  -d '{"url": "https://hooks.example.com/keenauth/changelog", "categories": ["deprecation", "security"]}'