HLAI Experts

Guide · Call transcripts

Getting HighLevel call transcripts through the API

Call the transcription route, not the recording route. GoHighLevel (GHL) returns a call's transcript from GET /conversations/locations/{locationId}/messages/{messageId}/transcription, and the audio from a separate recording path that puts the two IDs in the opposite order. Mix them up and you get a WAV file when you wanted text, or a 404.

Rob EasonPublished

Two endpoints that look alike

Both endpoints take the same two IDs: the sub-account's location ID and the message ID of the call. What differs is the order.

  • Transcript: /conversations/locations/{locationId}/messages/{messageId}/transcription
  • Recording: /conversations/messages/{messageId}/locations/{locationId}/recording
Location first for the transcript. Message first for the recording.

The 404 that looks like a missing transcript

The natural move is to take the recording path you already have working and swap its last segment for transcription. In our builds that guess returned a 404. It reads like “this call has no transcript,” when the real problem is the path.

The reverse mistake shows up too: a request to the recording path comes back as audio, in audio/x-wav, and code expecting JSON breaks on it. If you want both the audio and the text, make two calls to two paths.

Making the request

Each of these comes straight from HighLevel's transcription reference.

  1. Take the location ID of the sub-account and the message ID of the call. Both are required, and both are strings.
  2. Put them in the transcription path in that order: locations, then messages.
  3. Send a bearer token scoped to that sub-account.
  4. Send the Version header for the documentation version you're using. The transcription page pinned to 2021-04-15 asks for Version: 2021-04-15.

What comes back

The response is the call broken into sentences. Each one carries these fields, and it pays to keep all of them when you store it.

  • transcript: the text of that sentence.
  • sentenceIndex: its position, so you can put the call back in order.
  • startTime and endTime: where the sentence starts and stops, in milliseconds, so a reviewer can jump to that moment in the recording.
  • mediaChannel: the channel the sentence came from.
  • confidence: how sure the transcription is, useful for flagging lines a person should listen to.

Telling the two speakers apart

In our builds, mediaChannel was enough to separate one side of the call from the other without sending the audio to a second transcription service. HighLevel's schema doesn't say which channel value is the caller and which is the other party, though.

Work that out on a call you placed yourself, where you know who said what, and set your mapping from that. Don't promise anyone speaker labels until you have.

Parse it defensively

HighLevel's schema defines the times, index and confidence as numbers, but the example on the same page shows them in quotes, as strings. Check what real responses send before you fix the types in your parser.

Keep one API version throughout. The recording reference opens on HighLevel's newer v3 docs by default, while the transcription reference here is pinned to 2021-04-15. Confirm both endpoints on the same version before you ship code that calls them.

Some things this guide can't tell you: how soon after a call the transcript is ready, which OAuth scope the call needs, and what the response looks like when there's no transcript. Test those on your own account before you build a job that depends on them.

Rather have it set up for you?

We'd set up your calling, recordings and transcript pulls in HighLevel so every call can be read back, starting with a 30-minute 1:1 with Rob.

Book a 1:1 with Rob

Questions

Call transcript API questions

Why does the HighLevel transcription endpoint return 404?
The path is probably in the recording endpoint's order. The transcript path starts with locations and then messages; the recording path is the other way round.
Can I get the audio and the transcript in one request?
No. They are two endpoints. The recording path returns the audio as audio/x-wav, and the transcription path returns the text in sentences.
Does the transcript say who was speaking?
Each sentence carries a mediaChannel value, which in our builds was enough to split the two sides. HighLevel doesn't document which value is which, so map it from a test call first.
Which Version header does the transcription endpoint use?
The reference pinned to 2021-04-15 asks for Version: 2021-04-15. Other doc versions may show a different header, so pick one version and confirm every endpoint you call on it.
Are startTime and endTime in seconds?
No, milliseconds. Divide by 1,000 before you show a timestamp to a person.
Rob Eason

Who you talk to

Rob Eason

Rob runs HLAI Experts and takes the 1:1 calls himself.

He is a HighLevel Certified Admin with the second-most reviews in HighLevel's Certified Admin Directory worldwide, all of them 5 out of 5.

He won HighLevel's Top New Subaccounts via AI Employee award in its 2025 Summer of AI Awards and taught HighLevel's official masterclass on its AI Employee.

Before HighLevel, he co-owned a 60-employee financial services firm and sold his share.

On the call he looks at your account, not a script.

5/5 across 83 reviews in HighLevel's Certified Admin Directory