Zum Hauptinhalt springen
Webhooks benachrichtigen deine Systeme in Echtzeit, wenn Ereignisse in itellicoAI auftreten. Abonnements konfigurieren unter Entwickler → Webhooks. Siehe Webhooks für den UI-Einrichtungsablauf. Wenn du den Empfänger selbst implementierst, verwende den Webhook-Implementierungsleitfaden zusammen mit dieser Referenz.

Ereignistypen

conversation.started

Wird ausgelöst, wenn ein neues Gespräch beginnt (eingehend oder ausgehend). Wann es ausgelöst wird:
  • Ein eingehender Anruf wird von einem Agenten entgegengenommen
  • Ein ausgehender Kampagnenanruf wird verbunden
  • Ein Web- oder Test-Gespräch startet

conversation.ended

Wird ausgelöst, wenn ein Gespräch endet. Wann es ausgelöst wird:
  • Anruf endet normal (Anrufer oder Agent legt auf)
  • Anruf schlägt fehl (Verbindungsfehler, Timeout)
  • Anruf wird an ein anderes Ziel weitergeleitet
Statuswerte in der Nutzlast:
  • completed
  • failed
  • transferred

conversation.analysis.completed

Wird ausgelöst, wenn die gesammelten Insights eines Gesprächs die Verarbeitung abgeschlossen haben. Wann es ausgelöst wird:
  • Nach conversation.ended, sobald die Zielbewertung und Insight-Verarbeitung abgeschlossen sind
Enthält:
  • Ergebnisse der Zielanalyse
  • Ergebnisse der Post-Call-Analyse
  • Serialisierte Gesprächsnachrichten und -ereignisse, die als Analysekontext verwendet werden
Dieses Ereignis wird separat von conversation.ended ausgelöst, da die Analyse asynchron nach Gesprächsende läuft. Wenn du sowohl das Gesprächsergebnis als auch die Analysedaten benötigst, abonniere dieses Ereignis.

Nutzlastformat

Alle Webhook-Nutzlasten verwenden einen gemeinsamen Umschlag. data enthält die ereignisspezifischen Felder.
{
  "event_id": "3a8d4e3f-2f36-4cf7-9d4f-2df8e7f6f1c8",
  "event_type": "conversation.ended",
  "created": "2026-04-19T14:30:00.000000+00:00",
  "organization_uuid": "8702eb05-d00c-420d-bbbf-fed4b17b8b64",
  "organization_name": "Acme Support",
  "data": {
    "conversation_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Beispiel: conversation.started

{
  "event_id": "3a8d4e3f-2f36-4cf7-9d4f-2df8e7f6f1c8",
  "event_type": "conversation.started",
  "created": "2026-04-19T14:30:00.000000+00:00",
  "organization_uuid": "8702eb05-d00c-420d-bbbf-fed4b17b8b64",
  "organization_name": "Acme Support",
  "data": {
    "conversation_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "agent_uuid": "7b0a1a3d-59c6-46d4-8016-c5ccd5df6864",
    "agent_name": "Concierge",
    "direction": "inbound",
    "channel": "sip",
    "from_number": "+4312345678",
    "to_number": "+43720123456",
    "started_at": "2026-04-19T14:30:00.000Z"
  }
}

Beispiel: conversation.ended

{
  "event_id": "4c1c44a1-37b8-4d35-b0bc-4d03ad08e601",
  "event_type": "conversation.ended",
  "created": "2026-04-19T14:35:42.000000+00:00",
  "organization_uuid": "8702eb05-d00c-420d-bbbf-fed4b17b8b64",
  "organization_name": "Acme Support",
  "data": {
    "conversation_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "agent_uuid": "7b0a1a3d-59c6-46d4-8016-c5ccd5df6864",
    "agent_name": "Concierge",
    "direction": "inbound",
    "channel": "sip",
    "status": "completed",
    "from_number": "+4312345678",
    "to_number": "+43720123456",
    "started_at": "2026-04-19T14:30:00.000Z",
    "ended_at": "2026-04-19T14:35:42.000Z",
    "duration_seconds": 342,
    "answer_status": "human",
    "messages": [],
    "events": []
  }
}

Beispiel: conversation.analysis.completed

{
  "event_id": "bb164f3d-c4c7-41a1-8b4e-1abdb7f2d0b2",
  "event_type": "conversation.analysis.completed",
  "created": "2026-04-19T14:36:15.000000+00:00",
  "organization_uuid": "8702eb05-d00c-420d-bbbf-fed4b17b8b64",
  "organization_name": "Acme Support",
  "data": {
    "conversation_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "agent_uuid": "7b0a1a3d-59c6-46d4-8016-c5ccd5df6864",
    "agent_name": "Concierge",
    "analysis_job_uuid": "d86eab3a-142e-43b5-9b0b-c968e30f472d",
    "analyzed_at": "2026-04-19T14:36:15.000Z",
    "model_used": "gpt-4.1-mini",
    "results": {
      "goals": [],
      "post_call": [
        {
          "name": "Customer Satisfaction",
          "type": "rating",
          "value": 4,
          "reasoning": "Caller thanked the agent and expressed appreciation."
        }
      ]
    },
    "messages": [],
    "events": []
  }
}

Signaturverifizierung

Wenn du ein Signing-Secret konfiguriert hast, verifiziere die Webhook-Authentizität, indem du eine HMAC-SHA256-Signatur über <rawBody>.<timestamp> berechnest.
import hmac
import hashlib

def verify_signature(payload_body, timestamp, signature_header, secret):
    signature_base = payload_body + b"." + timestamp.encode()
    expected = hmac.new(
        secret.encode(),
        signature_base,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)
import crypto from "node:crypto";

function verifySignature(
  payloadBody: string,
  timestamp: string,
  signatureHeader: string,
  secret: string,
) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${payloadBody}.${timestamp}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected, "utf8"),
    Buffer.from(signatureHeader, "utf8"),
  );
}
Vergleiche Signaturen immer mit einer Timing-Safe-Vergleichsfunktion, um Timing-Angriffe zu verhindern.

Ereignisdaten-Felder

Daten von conversation.started

Gemeinsame Felder:
  • conversation_uuid
  • agent_uuid, agent_name
  • channel
  • started_at
  • from_number, to_number
  • ip_address
  • campaign_uuid, campaign_contact_uuid
  • direction
  • room_sid
  • metadata

Daten von conversation.ended

Enthält alles, was für die Ergebnisverarbeitung benötigt wird:
  • conversation_uuid
  • agent_uuid, agent_name
  • channel
  • status
  • started_at, ended_at, duration_seconds
  • from_number, to_number, ip_address
  • campaign_uuid, campaign_contact_uuid
  • direction, room_sid
  • metadata
  • answer_status
  • messages (serialisierte Transkriptnachrichten)
  • events (serialisierte Zeitachsenereignisse)

Daten von conversation.analysis.completed

Enthält Analyseausgabe plus Gesprächskontext:
  • conversation_uuid
  • agent_uuid, agent_name
  • analysis_job_uuid
  • analyzed_at
  • model_used
  • results.goals
  • results.post_call
  • messages
  • events

Zustellungs-Header

Signaturverifizierung

Jede Zustellung enthält Basis-Header:
  • Content-Type: application/json
  • User-Agent: itellicoAI-Webhook/1.0
  • X-Webhook-Event-Type
  • X-Webhook-Version: 1.0
  • X-Webhook-Event-Id
Wenn ein Webhook-Secret konfiguriert ist, enthalten Zustellungen zusätzlich:
  • X-Webhook-Timestamp
  • X-Webhook-Signature-256
Die Signatur ist HMAC-SHA256 über:
<json_payload>.<timestamp>
Dabei ist <json_payload> der genaue JSON-String, der im Body gesendet wird.

Verifikations-Pseudocode

const expected = hmacSha256Hex(secret, `${rawBody}.${timestamp}`);
const isValid = timingSafeEqual(expected, signatureHeader);
Ablehnen, wenn:
  • Signatur stimmt nicht überein
  • Zeitstempel liegt außerhalb deines Replay-Fensters
  • Erforderliche Header fehlen

Wiederholungslogik

Wenn dein Endpunkt einen Nicht-2xx-Status zurückgibt oder das Timeout überschreitet, werden Zustellungen automatisch wiederholt. Aktuelles Verhalten:
  • maximale Wiederholungen: 5
  • Basis-Wiederholungsverzögerung: 30s
  • Backoff: exponentiell (begrenzt)
  • Anfrage-Timeout: 10s
Inaktive Abonnements werden übersprungen. Zustellungsversuche werden pro Webhook-Abonnement protokolliert.

Benutzerdefinierte Header

Du kannst benutzerdefinierte Header pro Abonnement für Auth/Routing konfigurieren (zum Beispiel deinen eigenen Bearer-Token-Header).

Nächste Schritte

Webhooks einrichten

Webhook-Abonnements in der Account-UI konfigurieren

Webhook-Implementierungsleitfaden

Den empfangenden Endpunkt erstellen und Ereignisse sicher verarbeiten

Insights sammeln

Insights konfigurieren, die conversation.analysis.completed auslösen

API-Referenz

Vollständige API-Dokumentation anzeigen

Gesprächsziele

Ziele konfigurieren, die in Analyseereignissen enthalten sind