curl --request GET \
--url https://voice.growdental.ai/api/partner/v1/calls/{callId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://voice.growdental.ai/api/partner/v1/calls/{callId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://voice.growdental.ai/api/partner/v1/calls/{callId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://voice.growdental.ai/api/partner/v1/calls/{callId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://voice.growdental.ai/api/partner/v1/calls/{callId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://voice.growdental.ai/api/partner/v1/calls/{callId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://voice.growdental.ai/api/partner/v1/calls/{callId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"direction": "inbound",
"status": "<string>",
"outcome": "appointment_booked",
"duration_seconds": 123,
"summary": "<string>",
"started_at": "2023-11-07T05:31:56Z",
"ended_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"has_recording": true,
"has_transcript": true,
"practice_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"transcript": [
{
"role": "agent",
"message": "<string>",
"t": 123
}
]
}Get a call
Returns a single call, including its outcome, duration, and summary.
Requires calls:read.
The transcript field is present only when your key (and, where the
practice grant narrows scopes, the grant) holds transcripts:read
and your app has a signed BAA on file. When permitted, it is an
array of { role, message, t } turns (null for calls without a
stored transcript); otherwise the field is omitted entirely.
curl --request GET \
--url https://voice.growdental.ai/api/partner/v1/calls/{callId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://voice.growdental.ai/api/partner/v1/calls/{callId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://voice.growdental.ai/api/partner/v1/calls/{callId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://voice.growdental.ai/api/partner/v1/calls/{callId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://voice.growdental.ai/api/partner/v1/calls/{callId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://voice.growdental.ai/api/partner/v1/calls/{callId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://voice.growdental.ai/api/partner/v1/calls/{callId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"direction": "inbound",
"status": "<string>",
"outcome": "appointment_booked",
"duration_seconds": 123,
"summary": "<string>",
"started_at": "2023-11-07T05:31:56Z",
"ended_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"has_recording": true,
"has_transcript": true,
"practice_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"transcript": [
{
"role": "agent",
"message": "<string>",
"t": 123
}
]
}Authorizations
Partner API key sent as a Bearer token:
Authorization: Bearer gd_live_...
Keys are issued by the GrowDental team (invite-only), shown once
at creation, and stored server-side only as a SHA-256 hash. Key format:
gd_live_ (or gd_test_) followed by a 43-character base62 secret
(~256 bits of entropy). To rotate, request a new key, deploy it, then
ask us to revoke the old one — both keys work during the overlap.
Path Parameters
Call ID.
Response
The call.
A single call. Includes practice_id; the transcript field is
present only when your effective scopes include transcripts:read
and your app has a signed BAA (omitted otherwise).
Call ID.
inbound, outbound Call lifecycle status (e.g. initiated, in_progress, completed, failed).
Outcome classification set by post-call processing (e.g.
appointment_booked, callback_requested, voicemail,
no_answer, not_interested). null until the call completes
and is classified. Treat unknown values as informational — new
outcomes may be added without an API version bump.
"appointment_booked"
Call duration in seconds; null while in flight or if never connected.
Short natural-language summary of the conversation.
True when a recording is available via GET /calls/{callId}/recording.
True when a transcript exists (readable with transcripts:read + BAA).
Practice the call belongs to.
Full conversation transcript as { role, message, t } turns.
Present only when your key (and practice grant, where it
narrows) holds transcripts:read and your app has a
signed BAA; null for calls without a stored transcript.
Show child attributes
Show child attributes