TrustCaller HQ — San Francisco, CA
f in S

TrustCaller API

A REST API for programmatic, read-only access to your TrustCaller account — reserved numbers, call detail records, and live-call checks.

Introduction

All endpoints return JSON and are served over HTTPS. The base URL is:

https://trustcaller.net/api/v1

Every request must send Accept: application/json. All data endpoints are read-only and scoped to your account.

Authentication

The API uses Bearer token authentication. Generate an API key from your dashboard: Profile → API Keys → Generate New Key. The full token is shown once, at creation — store it securely. Managing API keys requires the api_keys_manage permission, and calling any API endpoint requires the api_access permission; an administrator grants these per account.

Send the token on every request:

Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Keep tokens secret. Never commit a token to version control — store it in an environment variable or a secret manager.

Rate limits

Requests are limited to 60 per minute. Exceeding the limit returns HTTP 429 Too Many Requests with a Retry-After header (seconds until reset).

Number format

Phone numbers are E.164, digits only — no leading +, no leading zero (for example 120000486562997). The /calls/check endpoint matches the supplied number exactly against this format.

Errors

StatusMeaning
200Success
201Resource created (API key)
401Missing or invalid token
403Token valid but the account lacks the required permission
404Resource not found, or not owned by you
422Validation error — see the response body
429Rate limit exceeded
500Server error
401 — no / invalid token
{ "message": "Unauthenticated." }
403 — missing permission
{ "message": "This action is unauthorized." }
422 — validation error
{
  "message": "The number field is required.",
  "errors": { "number": ["The number field is required."] }
}

List numbers

GET /api/v1/numbers requires api_access

Returns your reserved (active) numbers, paginated.

Query parameters

NameInTypeDescription
per_pagequeryintegeroptionalItems per page, 1–1000 (default 100)
pagequeryintegeroptionalPage number (default 1)

Example request

// Node.js 18+ (built-in fetch)
const TOKEN = "YOUR_API_TOKEN";

const res = await fetch("https://trustcaller.net/api/v1/numbers?per_page=50", {
  headers: {
    "Authorization": `Bearer ${TOKEN}`,
    "Accept": "application/json",
  },
});

if (!res.ok) throw new Error(`API error ${res.status}`);
const body = await res.json();
console.log(body.data);          // array of numbers
console.log(body.meta.total);    // total count
<?php
// php list-numbers.php
$token = "YOUR_API_TOKEN";

$ch = curl_init("https://trustcaller.net/api/v1/numbers?per_page=50");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer {$token}",
        "Accept: application/json",
    ],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 200) {
    fwrite(STDERR, "API error {$status}\n");
    exit(1);
}
$body = json_decode($response, true);
print_r($body["data"]);
# pip install requests
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.get(
    "https://trustcaller.net/api/v1/numbers",
    params={"per_page": 50},
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Accept": "application/json",
    },
)
res.raise_for_status()
body = res.json()
print(body["data"])
print(body["meta"]["total"])
200 — response
{
  "data": [
    {
      "id": 12345,
      "number": "120000486562997",
      "reserved": true,
      "released_at": null,
      "ivr_id": null,
      "created_at": "2026-01-15T10:30:00+00:00"
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": null },
  "meta": { "current_page": 1, "per_page": 50, "total": 1 }
}

Test numbers

GET /api/v1/test-numbers requires api_access

Public test numbers for trialling a route before sending real traffic. The response is cached for 5 minutes.

Query parameters

NameInTypeDescription
prefixquerystringoptionalFilter by number prefix, digits only (e.g. 8613)

Example request

const TOKEN = "YOUR_API_TOKEN";

const res = await fetch(
  "https://trustcaller.net/api/v1/test-numbers?prefix=8613",
  { headers: { "Authorization": `Bearer ${TOKEN}`, "Accept": "application/json" } },
);
if (!res.ok) throw new Error(`API error ${res.status}`);
const body = await res.json();
console.log(body.data, body.count);
<?php
$token = "YOUR_API_TOKEN";

$ch = curl_init("https://trustcaller.net/api/v1/test-numbers?prefix=8613");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", "Accept: application/json"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 200) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
print_r(json_decode($response, true)["data"]);
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.get(
    "https://trustcaller.net/api/v1/test-numbers",
    params={"prefix": "8613"},
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
res.raise_for_status()
print(res.json()["data"])
200 — response
{
  "data": [
    { "prefix": "8613", "test_number": "8613912345678" }
  ],
  "count": 1,
  "cached_for_seconds": 300,
  "filtered_by_prefix": "8613"
}

List calls

GET /api/v1/calls requires api_access

Returns your call detail records (CDRs), most recent first, paginated. Caller numbers are partially masked for privacy.

Query parameters

NameInTypeDescription
fromquerydateoptionalStart date, YYYY-MM-DD
toquerydateoptionalEnd date, YYYY-MM-DD
per_pagequeryintegeroptionalItems per page, 1–1000 (default 100)

Example request

const TOKEN = "YOUR_API_TOKEN";

const url = "https://trustcaller.net/api/v1/calls"
  + "?from=2026-05-01&to=2026-05-15&per_page=100";
const res = await fetch(url, {
  headers: { "Authorization": `Bearer ${TOKEN}`, "Accept": "application/json" },
});
if (!res.ok) throw new Error(`API error ${res.status}`);
const body = await res.json();
console.log(body.data);
<?php
$token = "YOUR_API_TOKEN";
$url = "https://trustcaller.net/api/v1/calls?from=2026-05-01&to=2026-05-15";

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", "Accept: application/json"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 200) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
print_r(json_decode($response, true)["data"]);
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.get(
    "https://trustcaller.net/api/v1/calls",
    params={"from": "2026-05-01", "to": "2026-05-15", "per_page": 100},
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
res.raise_for_status()
print(res.json()["data"])
200 — response
{
  "data": [
    {
      "id": 98765,
      "caller_id": "8823412XXX",
      "number": "120000486562997",
      "start_at": "2026-05-15T14:30:00+00:00",
      "end_at": "2026-05-15T14:32:15+00:00",
      "duration": 135,
      "pdd": 850,
      "call_unique_id": "abc123-xyz789",
      "call_acceptable": true,
      "short_call": false,
      "hang_cause": "NORMAL_CLEARING"
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": null },
  "meta": { "current_page": 1, "per_page": 100, "total": 1 }
}

Get a call

GET /api/v1/calls/{id} requires api_access

Returns a single call detail record by its numeric ID. Records that do not belong to your account return 404.

Path parameters

NameInTypeDescription
idpathintegerrequiredThe call record ID

Example request

const TOKEN = "YOUR_API_TOKEN";

const res = await fetch("https://trustcaller.net/api/v1/calls/98765", {
  headers: { "Authorization": `Bearer ${TOKEN}`, "Accept": "application/json" },
});
if (res.status === 404) { console.log("Call not found"); }
else if (!res.ok) { throw new Error(`API error ${res.status}`); }
else { console.log((await res.json()).data); }
<?php
$token = "YOUR_API_TOKEN";

$ch = curl_init("https://trustcaller.net/api/v1/calls/98765");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", "Accept: application/json"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status === 404) { echo "Call not found\n"; exit; }
if ($status !== 200) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
print_r(json_decode($response, true)["data"]);
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.get(
    "https://trustcaller.net/api/v1/calls/98765",
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
if res.status_code == 404:
    print("Call not found")
else:
    res.raise_for_status()
    print(res.json()["data"])
200 — response
{
  "data": {
    "id": 98765,
    "caller_id": "8823412XXX",
    "number": "120000486562997",
    "start_at": "2026-05-15T14:30:00+00:00",
    "end_at": "2026-05-15T14:32:15+00:00",
    "duration": 135,
    "pdd": 850,
    "call_unique_id": "abc123-xyz789",
    "call_acceptable": true,
    "short_call": false,
    "hang_cause": "NORMAL_CLEARING"
  }
}
404 — not found
{ "error": "not_found", "message": "Call record not found." }

Check live call

GET /api/v1/calls/check requires api_access

A connectivity check: returns whether a live, answered call is currently present on one of your numbers. Useful as a smoke-test — place a call into the platform, then confirm it landed. The response is a strict boolean and carries no call details.

The number is matched exactly in E.164 digits-only form (no +, no leading zero). A call on another account's number is never visible to you — the check returns false.

Query parameters

NameInTypeDescription
numberquerystringrequiredThe destination number to check (E.164, digits only)

Example request

const TOKEN = "YOUR_API_TOKEN";

const res = await fetch(
  "https://trustcaller.net/api/v1/calls/check?number=120000486562997",
  { headers: { "Authorization": `Bearer ${TOKEN}`, "Accept": "application/json" } },
);
if (!res.ok) throw new Error(`API error ${res.status}`);
const { call_received } = await res.json();
console.log(call_received ? "Call landed" : "No live call");
<?php
$token = "YOUR_API_TOKEN";
$url = "https://trustcaller.net/api/v1/calls/check?number=120000486562997";

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", "Accept: application/json"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 200) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
$received = json_decode($response, true)["call_received"];
echo $received ? "Call landed\n" : "No live call\n";
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.get(
    "https://trustcaller.net/api/v1/calls/check",
    params={"number": "120000486562997"},
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
res.raise_for_status()
print("Call landed" if res.json()["call_received"] else "No live call")
200 — response
{ "call_received": true }

Create an API key

POST /api/v1/auth/keys requires api_keys_manage

Generates a new API key. The full token is returned once — store it immediately. Most users create their first key from the dashboard (Profile → API Keys); this endpoint is for programmatic key rotation.

Body parameters (JSON)

NameInTypeDescription
namebodystringrequiredA label for the key, max 64 characters

Example request

const TOKEN = "YOUR_API_TOKEN";

const res = await fetch("https://trustcaller.net/api/v1/auth/keys", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${TOKEN}`,
    "Accept": "application/json",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "Production server" }),
});
if (res.status !== 201) throw new Error(`API error ${res.status}`);
const body = await res.json();
console.log("Save this token now:", body.token);
<?php
$token = "YOUR_API_TOKEN";

$ch = curl_init("https://trustcaller.net/api/v1/auth/keys");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode(["name" => "Production server"]),
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer {$token}",
        "Accept: application/json",
        "Content-Type: application/json",
    ],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 201) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
echo "Save this token now: " . json_decode($response, true)["token"] . "\n";
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.post(
    "https://trustcaller.net/api/v1/auth/keys",
    json={"name": "Production server"},
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
if res.status_code != 201:
    raise SystemExit(f"API error {res.status_code}")
print("Save this token now:", res.json()["token"])
201 — response
{
  "id": 7,
  "name": "Production server",
  "token": "7|aBcD...long-token-shown-once",
  "created_at": "2026-05-16T09:00:00+00:00",
  "message": "Save this token now. It cannot be retrieved later."
}

List API keys

GET /api/v1/auth/keys requires api_keys_manage

Lists your API keys — metadata only. Token values are never returned.

Example request

const TOKEN = "YOUR_API_TOKEN";

const res = await fetch("https://trustcaller.net/api/v1/auth/keys", {
  headers: { "Authorization": `Bearer ${TOKEN}`, "Accept": "application/json" },
});
if (!res.ok) throw new Error(`API error ${res.status}`);
console.log((await res.json()).data);
<?php
$token = "YOUR_API_TOKEN";

$ch = curl_init("https://trustcaller.net/api/v1/auth/keys");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", "Accept: application/json"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 200) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
print_r(json_decode($response, true)["data"]);
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.get(
    "https://trustcaller.net/api/v1/auth/keys",
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
res.raise_for_status()
print(res.json()["data"])
200 — response
{
  "data": [
    {
      "id": 7,
      "name": "Production server",
      "last_used_at": "2026-05-16T09:05:00+00:00",
      "created_at": "2026-05-16T09:00:00+00:00"
    }
  ],
  "count": 1
}

Revoke an API key

DELETE /api/v1/auth/keys/{id} requires api_keys_manage

Revokes an API key. The key stops working immediately. Revoking a key that does not belong to you returns 404.

Path parameters

NameInTypeDescription
idpathintegerrequiredThe API key ID

Example request

const TOKEN = "YOUR_API_TOKEN";

const res = await fetch("https://trustcaller.net/api/v1/auth/keys/7", {
  method: "DELETE",
  headers: { "Authorization": `Bearer ${TOKEN}`, "Accept": "application/json" },
});
if (res.status === 404) { console.log("Key not found"); }
else if (!res.ok) { throw new Error(`API error ${res.status}`); }
else { console.log("Key revoked"); }
<?php
$token = "YOUR_API_TOKEN";

$ch = curl_init("https://trustcaller.net/api/v1/auth/keys/7");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "DELETE",
    CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}", "Accept: application/json"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status === 404) { echo "Key not found\n"; exit; }
if ($status !== 200) { fwrite(STDERR, "API error {$status}\n"); exit(1); }
echo "Key revoked\n";
import requests

TOKEN = "YOUR_API_TOKEN"

res = requests.delete(
    "https://trustcaller.net/api/v1/auth/keys/7",
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
if res.status_code == 404:
    print("Key not found")
else:
    res.raise_for_status()
    print("Key revoked")
200 — response
{ "message": "API key revoked." }

TrustCaller API · v1 · Public Beta · Last updated 2026-05-16