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

# AI Agent Call Webhook Payload

> Schema reference for the webhook payload Zeeg sends when an AI agent call completes, including the outcome, transcript summary, collected data, actions, and any booking made.

<Badge color="orange">Alpha</Badge>

This payload is delivered to your webhook callback URL when an `ai_agent.call_completed` event occurs. It fires once when an AI agent call reaches a terminal state. This webhook is in alpha: the payload shape may still change without a deprecation cycle.

## Event Info

<ResponseField name="event" type="string" required>
  Always `"ai_agent.call_completed"`.
</ResponseField>

<ResponseField name="conversationId" type="string" required>
  Unique identifier for this call. Use this as the dedup key for idempotent processing — in rare cases the same call may be delivered more than once. A delivery that fails is not retried.
</ResponseField>

## Agent

<ResponseField name="agentId" type="string" required>
  UUID of the AI agent that handled the call.
</ResponseField>

<ResponseField name="agentName" type="string | null">
  Display name of the AI agent.
</ResponseField>

## Call

<ResponseField name="direction" type="string" required>
  `"inbound"` (caller reached the agent) or `"outbound"` (agent dialled out).
</ResponseField>

<ResponseField name="callOutcome" type="string" required>
  Terminal outcome of the call attempt: `"answered"`, `"voicemail"`, `"not_answered"`, `"busy"`, or `"unknown"`.
</ResponseField>

<ResponseField name="isCall" type="boolean" required>
  `true` when the interaction was a real phone call; `false` for non-call interactions such as chat.
</ResponseField>

<ResponseField name="startedAt" type="string | null">
  ISO 8601 UTC timestamp when the call started.
</ResponseField>

<ResponseField name="endedAt" type="string | null">
  ISO 8601 UTC timestamp when the call ended.
</ResponseField>

<ResponseField name="durationSeconds" type="integer | null">
  Total call duration in seconds.
</ResponseField>

<ResponseField name="contactPhoneNumber" type="string | null">
  The external party's (contact/lead) phone number in E.164 format, regardless of call direction. `null` for test/widget calls or blocked caller ID.
</ResponseField>

<ResponseField name="contactName" type="string | null">
  The contact's name. It is the name the caller stated on this call, else the full name sent to the outbound call API, else the name of the matched CRM contact. `null` when none is known.
</ResponseField>

<ResponseField name="contactEmail" type="string | null">
  The contact's email address. It is the address the caller stated on this call, else the email sent to the outbound call API, else the email of the matched CRM contact. `null` when none is known.
</ResponseField>

<ResponseField name="agentPhoneNumber" type="string | null">
  The agent's phone line that the call used, in E.164 format. If the call never connected, this is the agent's current provisioned number. `null` when neither is known.
</ResponseField>

<ResponseField name="agentLanguage" type="string | null">
  The agent's primary language code, for example `de` or `en`.
</ResponseField>

<ResponseField name="conversationLanguage" type="string | null">
  The language code the conversation was held in, as detected on the call, for example `de`. It can differ from `agentLanguage` on a multilingual agent. `null` when no language was detected.
</ResponseField>

## Transcript

<ResponseField name="transcript" type="array" required>
  Ordered conversation turns. Tool-only turns with no spoken message are omitted — the actions the agent took are in `actions`.

  <Expandable title="Transcript turn">
    <ResponseField name="role" type="string">
      Who spoke the turn. Example: `agent`, `user`.
    </ResponseField>

    <ResponseField name="message" type="string">
      The spoken text of the turn.
    </ResponseField>

    <ResponseField name="timeInCallSeconds" type="integer | null">
      Offset in seconds from the start of the call when the turn occurred.
    </ResponseField>
  </Expandable>
</ResponseField>

## Conversation Analysis

<ResponseField name="conversationAnalysis" type="object">
  AI-generated analysis of the conversation.

  <Expandable title="Conversation analysis object">
    <ResponseField name="transcriptSummary" type="string | null">
      AI-generated narrative summary of the transcript.
    </ResponseField>

    <ResponseField name="collectedData" type="object">
      Map of collected field id to its `{ value, type }` entry. Keys are the data the agent collects — e.g. `name`, `email`, `phone`, `message`, `summary`, plus any custom fields. Keys depend on your agent's configuration.

      <Expandable title="Collected field entry">
        <ResponseField name="value" type="string | null">
          The value the agent collected for this field.
        </ResponseField>

        <ResponseField name="type" type="string | null">
          The field's data type (e.g. `string`). `null` when unknown.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## System notes

<ResponseField name="systemNotes" type="array" required>
  Notes Zeeg adds about the call, beside what the agent collected. An empty array when there is nothing to note. New notes can be added at any time, so ignore a `code` you do not recognize rather than failing on it.

  <Expandable title="System note object">
    <ResponseField name="code" type="string | null">
      Stable identifier to branch on. `null` for a note that is informational text only.

      * `caller_phone_not_dialable` — the callback number the caller stated is not a dialable phone number. `conversationAnalysis.collectedData.phone` holds it exactly as the caller gave it.
    </ResponseField>

    <ResponseField name="message" type="string">
      English, human-readable description of the note. The wording can change; branch on `code`.
    </ResponseField>
  </Expandable>
</ResponseField>

## Actions

<ResponseField name="actions" type="array" required>
  Ordered list of actions the agent executed during the call.

  <Expandable title="Action object">
    <ResponseField name="type" type="string">
      Action identifier. Example: `book_event`, `send_email`, `send_sms`.
    </ResponseField>

    <ResponseField name="routeId" type="string | null">
      UUID of the route configuration that drove the action, if applicable. `null` otherwise.
    </ResponseField>

    <ResponseField name="calledAt" type="string | null">
      ISO 8601 timestamp when this action was executed.
    </ResponseField>
  </Expandable>
</ResponseField>

## Booking

<ResponseField name="booking" type="object | null">
  The scheduled event created during the call, in the same shape as the `GET /v2/scheduled-events/{uuid}` resource; `null` if no booking was made. Correlate `booking.uuid` with `invitee.scheduled` webhook events for the same booking.

  <Expandable title="Booking object">
    <ResponseField name="uri" type="string">
      Public API URI of the scheduled event resource.
    </ResponseField>

    <ResponseField name="uuid" type="string">
      Unique identifier of the scheduled event. Use this to correlate with `invitee.scheduled` webhook events.
    </ResponseField>

    <ResponseField name="title" type="string">
      Title of the scheduled event.
    </ResponseField>

    <ResponseField name="type" type="string">
      Event type kind. Example: `ONE_ON_ONE`, `GROUP`, `ROUND_ROBIN`.
    </ResponseField>

    <ResponseField name="startTime" type="string">
      ISO 8601 UTC start time of the booked event.
    </ResponseField>

    <ResponseField name="endTime" type="string">
      ISO 8601 UTC end time of the booked event.
    </ResponseField>

    <ResponseField name="duration" type="integer">
      Event duration in minutes.
    </ResponseField>

    <ResponseField name="status" type="string">
      Booking status. Example: `confirmed`, `cancelled`.
    </ResponseField>

    <ResponseField name="eventTypeUri" type="string">
      Public API URI of the event type this booking was made against.
    </ResponseField>

    <ResponseField name="location" type="object | null">
      Meeting location for the booking.

      <Expandable title="Location object">
        <ResponseField name="type" type="string">
          Location type. Example: `google_meet`, `zoom`, `phone`, `in_person`.
        </ResponseField>

        <ResponseField name="joinUrl" type="string | null">
          Join URL for the meeting, when applicable.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="maxActiveInvitees" type="integer">
      Maximum number of active invitees the event allows.
    </ResponseField>

    <ResponseField name="activeInviteesCount" type="integer">
      Current number of active (non-cancelled) invitees.
    </ResponseField>

    <ResponseField name="invitees" type="array">
      Invitees booked on the scheduled event.

      <Expandable title="Invitee object">
        <ResponseField name="uuid" type="string">
          Unique identifier of the invitee.
        </ResponseField>

        <ResponseField name="salutation" type="string | null">
          Salutation for the invitee, if collected.
        </ResponseField>

        <ResponseField name="fullName" type="string | null">
          Full name of the invitee.
        </ResponseField>

        <ResponseField name="email" type="string | null">
          Email address of the invitee.
        </ResponseField>

        <ResponseField name="guests" type="array">
          Additional guest email addresses for this invitee.
        </ResponseField>

        <ResponseField name="timeZone" type="string | null">
          IANA time zone of the invitee.
        </ResponseField>

        <ResponseField name="cancellation" type="object">
          Cancellation details. All fields are `null` when the invitee is not cancelled.

          <Expandable title="Cancellation object">
            <ResponseField name="cancelledAt" type="string | null">
              ISO 8601 UTC timestamp when the invitee was cancelled.
            </ResponseField>

            <ResponseField name="cancelledBy" type="string | null">
              Identifier of who cancelled the booking.
            </ResponseField>

            <ResponseField name="cancellerType" type="string | null">
              Type of canceller (e.g. host, invitee).
            </ResponseField>

            <ResponseField name="cancellationReason" type="string | null">
              Reason given for the cancellation.
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="payment" type="object | null">
          Payment details for the booking, or `null` when no payment applies.
        </ResponseField>

        <ResponseField name="questions" type="array">
          Booking questions answered by the invitee.
        </ResponseField>

        <ResponseField name="scheduledAt" type="string | null">
          ISO 8601 UTC timestamp when the invitee booked.
        </ResponseField>

        <ResponseField name="utm" type="object">
          UTM tracking parameters captured at booking time. Holds all five keys (`utm_campaign`, `utm_source`, `utm_medium`, `utm_term`, `utm_content`); a key holds `null` when the booking did not carry a value for it.
        </ResponseField>

        <ResponseField name="customQueryParams" type="object">
          Custom query parameters captured at booking time. An empty object when the booking captured none.
        </ResponseField>

        <ResponseField name="agentBookingReference" type="string | null">
          Reference code for bookings made via the AI agent; `null` otherwise.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="guests" type="array">
      Event-level guest email addresses.
    </ResponseField>

    <ResponseField name="hosts" type="array">
      Hosts assigned to the scheduled event.

      <Expandable title="Host object">
        <ResponseField name="firstName" type="string | null">
          Host's first name.
        </ResponseField>

        <ResponseField name="lastName" type="string | null">
          Host's last name.
        </ResponseField>

        <ResponseField name="email" type="string | null">
          Host's email address.
        </ResponseField>

        <ResponseField name="slug" type="string | null">
          Host's public profile slug.
        </ResponseField>

        <ResponseField name="url" type="string | null">
          Host's public profile URL.
        </ResponseField>

        <ResponseField name="avatarUrl" type="string | null">
          URL of the host's avatar image, if set.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="teamName" type="string | null">
      Name of the team that owns the scheduling page the booking was made on, `null` for a personal
      scheduling page.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 UTC timestamp when the booking was created.
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      ISO 8601 UTC timestamp when the booking was last updated.
    </ResponseField>

    <ResponseField name="currentTime" type="string">
      ISO 8601 UTC server time when the resource was rendered.
    </ResponseField>
  </Expandable>
</ResponseField>

## CRM

<ResponseField name="crmPersonId" type="string | null">
  UUID of the CRM person record linked to this call, if matched.
</ResponseField>

## Outbound Call

<ResponseField name="outboundCall" type="object | null">
  What you sent to the outbound-call API when you started this call. `null` for an inbound call and for an outbound call that the outbound-call API did not start.

  <Expandable title="Outbound call">
    <ResponseField name="id" type="string">
      The `id` that the outbound-call API returned.
    </ResponseField>

    <ResponseField name="fullName" type="string | null">
      The contact name you sent.
    </ResponseField>

    <ResponseField name="email" type="string | null">
      The contact email you sent.
    </ResponseField>

    <ResponseField name="additionalData" type="string | null">
      The additional context you sent for the agent.
    </ResponseField>

    <ResponseField name="scheduledTime" type="string | null">
      ISO 8601 UTC time the call was scheduled for.
    </ResponseField>
  </Expandable>
</ResponseField>

## Full Payload Example

```json theme={null}
{
  "event": "ai_agent.call_completed",
  "conversationId": "abc1234-0000-0000-0000-xyz987654321",
  "agentId": "9a39bf60-a6c3-45e7-80cd-2cd36e520861",
  "agentName": "Sales Agent",
  "direction": "inbound",
  "callOutcome": "answered",
  "isCall": true,
  "startedAt": "2026-06-01T10:00:00+00:00",
  "endedAt": "2026-06-01T10:01:30+00:00",
  "durationSeconds": 90,
  "contactPhoneNumber": "+4917612345678",
  "contactName": "Alice Example",
  "contactEmail": "alice@example.com",
  "agentPhoneNumber": "+4989123456789",
  "agentLanguage": "de",
  "conversationLanguage": "de",
  "transcript": [
    { "role": "agent", "message": "Hello, thank you for calling. How can I help you today?", "timeInCallSeconds": 0 },
    { "role": "user", "message": "Hi, I'd like to know more about your pricing.", "timeInCallSeconds": 4 },
    { "role": "agent", "message": "Of course. Our plans start at 12 euros per month. Shall I book a follow-up call?", "timeInCallSeconds": 9 }
  ],
  "conversationAnalysis": {
    "transcriptSummary": "The caller asked about product pricing and requested a follow-up call next week.",
    "collectedData": {
      "name":    { "value": "Alice Müller", "type": "string" },
      "email":   { "value": "alice@example.com", "type": "string" },
      "message": { "value": "Please send me the pricing sheet.", "type": "string" },
      "summary": { "value": "Caller asked about pricing and wants a follow-up.", "type": "string" }
    }
  },
  "systemNotes": [],
  "actions": [
    {
      "type": "book_event",
      "routeId": null,
      "calledAt": "2026-06-01T10:00:45+00:00"
    },
    {
      "type": "send_email",
      "routeId": "9b1c2d3e-4f56-7890-abcd-ef0123456789",
      "calledAt": "2026-06-01T10:01:20+00:00"
    }
  ],
  "booking": {
    "uri": "https://api.zeeg.me/v2/scheduled-events/zg-O69bd55e004c8b",
    "uuid": "zg-O69bd55e004c8b",
    "title": "30-Minute Meeting with Sales Agent",
    "type": "ONE_ON_ONE",
    "startTime": "2026-06-03T14:00:00.000000Z",
    "endTime": "2026-06-03T14:30:00.000000Z",
    "duration": 30,
    "status": "confirmed",
    "eventTypeUri": "https://api.zeeg.me/v2/event-types/80f46bf5-eb01-4c07-960e-a9a3e18aae5e",
    "location": { "type": "google_meet", "joinUrl": "https://meet.google.com/abc-defg-hij" },
    "maxActiveInvitees": 1,
    "activeInviteesCount": 1,
    "invitees": [
      {
        "uuid": "zg-A12cd34ef005a9c",
        "salutation": null,
        "fullName": "Alice Müller",
        "email": "alice@example.com",
        "guests": [],
        "timeZone": "Europe/Berlin",
        "cancellation": { "cancelledAt": null, "cancelledBy": null, "cancellerType": null, "cancellationReason": null },
        "payment": null,
        "questions": [],
        "scheduledAt": "2026-06-01T10:00:50.000000Z",
        "utm": { "utm_campaign": null, "utm_source": null, "utm_medium": null, "utm_content": null, "utm_term": null },
        "customQueryParams": {},
        "agentBookingReference": "123456"
      }
    ],
    "guests": [],
    "hosts": [
      { "firstName": "Lena", "lastName": "Meier", "email": "lena.meier@example.com", "slug": "lena-meier", "url": "https://zeeg.me/lena-meier", "avatarUrl": null }
    ],
    "teamName": null,
    "createdAt": "2026-06-01T10:00:50.000000Z",
    "updatedAt": "2026-06-01T10:00:50.000000Z",
    "currentTime": "2026-06-01T10:01:30.000000Z"
  },
  "crmPersonId": "7f3e2a91-1234-4abc-9012-b3c456d78901",
  "outboundCall": null
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.