GoliathDevelopersGet an API key
Reference/Conversationsgenerated from the gateway manifest

getCallRecording

One call's RECORDING and TRANSCRIPT, plus the outcome logged for it.

POST/api/v1/callREADreadruns as the key's owner
View as Markdown

One call's RECORDING and TRANSCRIPT, plus the outcome logged for it: a time-limited signed audio URL (recordingUrl), the speaker-by-speaker transcript ({ speaker, text, start, end }), the AI summary, the dialer disposition + dispositionNote, direction, status, durationSeconds, createdAt, who handled it (author: a person or an AI employee) and both phone numbers. callId comes from a CALL row in listInboxThreads (its id, or any id in groupedCallIds), or from a CALL entry in listContactActivities. Returns NULL (not an error) when the call has NO RECORDING, when it is not your organization's, or when no such call exists; those three are indistinguishable by design, so a null is not evidence the call did not happen. A call with no recording has no transcript either, and no summary: the summary is enrichment derived from the recording. So for those calls read listContactActivities instead: its CALL entries carry direction, durationSeconds, status, disposition and dispositionNote for every call on a contact, recorded or not, which is the logged OUTCOME even when there is no audio. Reading here has NO side effect: it deliberately does not mark the call seen, so an agent sweeping calls cannot silently clear an operator's unread badges. recordingUrl expires; fetch it when you are about to use it rather than storing it, and re-run this operation to re-sign.

curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operationId": "getCallRecording",
    "variables": {
      "callId": "<callId>"
    }
  }'
import { GoliathClient } from '@goliath-data/sdk'

const goliath = new GoliathClient({
  apiKey: process.env.GOLIATH_API_KEY!,
  baseUrl: 'https://server.goliathdata.com',
})

const result = await goliath.conversations.getCallRecording({
  callId: '<callId>'
})
const res = await fetch('https://server.goliathdata.com/api/v1/call', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GOLIATH_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    operationId: 'getCallRecording',
    variables: {
      callId: '<callId>'
    }
  }),
})
const { data, errors } = await res.json()

Variables

The example sends only what the schema requires. Some operations also need one of several optional variables (one filter or another, say); the description above says which.

callIdID!required

Response

What comes back under data: a list shows as one entry, and a value as its type.

response shape
{
  "data": {
    "callsQuery": {
      "callRecording": {
        "id": "<ID>",
        "recordingUrl": "…",
        "transcript": [
          {
            "speaker": "…",
            "text": "…",
            "start": 0,
            "end": 0
          }
        ],
        "summary": "…",
        "disposition": "Connected",
        "dispositionNote": "…",
        "direction": "INBOUND",
        "status": "RINGING",
        "durationSeconds": 0,
        "createdAt": "2026-01-01T00:00:00.000Z",
        "seen": true,
        "contactName": "…",
        "contactE164PhoneNumber": "…",
        "fromPhoneNumber": "…",
        "toPhoneNumber": "…",
        "author": {
          "kind": "USER",
          "id": "<ID>",
          "name": "…"
        },
        "agentName": "…"
      }
    }
  }
}

Errors

Behaviour

A read. It rejects an Idempotency-Key header with 400 bad_request.