Logo
Search
API Docs

End-of-Call Report

Core Concepts

End-of-Call Report: Structure & Fields

Overview

The end-of-call-report server message is sent once to your configured Server URL after a call ends. It bundles the full record of the call — how it ended, its cost, its transcript and recorded audio, and (for enterprise accounts using a recording consent plan) a compliance record of consent. This page is a field-by-field reference for that payload. For the general webhook/server event catalog and handler examples, see Webhooks & Events; for how end-of-call-report is enabled via the serverMessages array, see Client Messages, Server Messages & Hook Configuration; for the recording consent feature itself, see Recording Consent Plan.


Standard Envelope & Core Fields

Like every server message, the report arrives wrapped in a message object whose type identifies the event:

{
  "message": {
    "type": "end-of-call-report",
    "endedReason": "hangup",
    "call": { /* Call Object */ },
    "startedAt": "2024-01-15T10:25:00Z",
    "endedAt": "2024-01-15T10:35:00Z",
    "cost": 0.15,
    "artifact": { /* see below */ }
  }
}

Core top-level fields:

  • type – always "end-of-call-report" for this event.
  • endedReason – why the call ended, for example "hangup" or "assistantEndedCall".
  • call – the full Call Object, with call metadata (assistant, phone number, customer, status, and so on).
  • startedAt / endedAt – ISO 8601 timestamps marking when the call began and ended.
  • cost – the total cost of the call.

The Artifact Object

The artifact object carries the durable record of what happened on the call:

  • recording – an object with URLs to the call's recorded audio.
  • transcript – a single plain-text string of the full conversation, formatted as alternating speaker lines (for example "AI: How can I help? User: What's the weather?").
  • messages – an array of conversation turns, each with a role ("assistant" or "user") and a message string:
"messages": [
  { "role": "assistant", "message": "How can I help?" },
  { "role": "user", "message": "What's the weather?" }
]

A second, OpenAI-formatted variant of the same conversation is also available on the artifact as messagesOpenAIFormatted, using the role/content shape OpenAI-compatible tools expect:

"messagesOpenAIFormatted": [
  { "role": "assistant", "content": "How can I help?" },
  { "role": "user", "content": "What's the weather?" }
]

Transcript and message generation depend on artifactPlan.transcriptPlan being enabled on the assistant; if it isn't, these fields may be sparse or absent.



Full Worked Example

A complete report combining the core fields, artifact, and compliance object:

{
  "message": {
    "type": "end-of-call-report",
    "endedReason": "assistantEndedCall",
    "call": {
      "id": "call-123",
      "assistantId": "asst-456",
      "status": "ended"
    },
    "startedAt": "2024-01-15T10:25:00Z",
    "endedAt": "2024-01-15T10:35:00Z",
    "cost": 0.15,
    "artifact": {
      "recording": {
        "stereoUrl": "https://storage.sulus.ai/recordings/call-123-stereo.wav",
        "mono": {
          "combinedUrl": "https://storage.sulus.ai/recordings/call-123-mono.wav"
        }
      },
      "transcript": "AI: For quality purposes this call may be recorded, do you consent? User: Yes. AI: Great, how can I help you today? User: I need to reschedule an appointment.",
      "messages": [
        { "role": "assistant", "message": "For quality purposes this call may be recorded, do you consent?" },
        { "role": "user", "message": "Yes." },
        { "role": "assistant", "message": "Great, how can I help you today?" },
        { "role": "user", "message": "I need to reschedule an appointment." }
      ],
      "messagesOpenAIFormatted": [
        { "role": "assistant", "content": "For quality purposes this call may be recorded, do you consent?" },
        { "role": "user", "content": "Yes." },
        { "role": "assistant", "content": "Great, how can I help you today?" },
        { "role": "user", "content": "I need to reschedule an appointment." }
      ]
    },
    "compliance": {
      "recordingConsent": {
        "type": "verbal",
        "grantedAt": "2024-01-15T10:25:08Z"
      }
    }
  }
}