curl --request GET \
--url https://api.optimaldial.com/api/v1/contacts/{contact_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.optimaldial.com/api/v1/contacts/{contact_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.optimaldial.com/api/v1/contacts/{contact_id}', 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://api.optimaldial.com/api/v1/contacts/{contact_id}",
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://api.optimaldial.com/api/v1/contacts/{contact_id}"
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://api.optimaldial.com/api/v1/contacts/{contact_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.optimaldial.com/api/v1/contacts/{contact_id}")
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",
"organization_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"phone": "+15551234567",
"properties": {},
"status": "queued",
"credits_charged": 1,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"optimaldial_status": "<string>",
"error_message": "<string>",
"validation_tier": "standard"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Retrieve a contact (legacy — no identity)
Legacy. Fully supported with no removal planned, but this response
does not include OptimalDial Identity: optimaldial_status reports the
Answer Intent value only.
Use GET /api/v2/contacts/{contact_id} for the nine-tier status and the
identity band. Existing integrations can stay here indefinitely.
curl --request GET \
--url https://api.optimaldial.com/api/v1/contacts/{contact_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.optimaldial.com/api/v1/contacts/{contact_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.optimaldial.com/api/v1/contacts/{contact_id}', 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://api.optimaldial.com/api/v1/contacts/{contact_id}",
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://api.optimaldial.com/api/v1/contacts/{contact_id}"
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://api.optimaldial.com/api/v1/contacts/{contact_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.optimaldial.com/api/v1/contacts/{contact_id}")
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",
"organization_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"phone": "+15551234567",
"properties": {},
"status": "queued",
"credits_charged": 1,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"optimaldial_status": "<string>",
"error_message": "<string>",
"validation_tier": "standard"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Authorizations
OptimalDial API key, prefixed od_live_, sent as Authorization: Bearer ....
Mint keys in the in-app developer panel; they are scoped to a single organization.
Path Parameters
Response
The contact.
E.164-normalized phone number (US/CA only).
"+15551234567"
Arbitrary extra fields echoed back from creation.
queued → processing → one of completed, failed, or
discarded. failed means processing finished without a result
for this contact; discarded means OptimalDial dropped it before
processing. Both refund the credit, both set error_message, and
both are delivered as a contact.failed event to your webhook
endpoints and the contact's callback_url — check status on
the payload to tell them apart.
queued, processing, completed, failed, discarded x >= 0The Answer Intent classification — e.g. "Likely Answer",
"Likely Voicemail". Populated when status == "completed".
This field is frozen on v1: it keeps returning the Answer Intent
value even for contacts processed with OptimalDial Identity, so
existing filters keep working. Use /api/v2/contacts for the
nine-tier status and the identity band.
Why the contact is failed or discarded; null otherwise.
Validation pricing tier this contact was created with.
standard, max