CallRing AI API reference
A read-only REST API for pulling your calls, recordings, messages, numbers, sources and campaigns as JSON. Create a scoped token in the Dev Portal, send it as a Bearer credential, and start reading your data.
https://app.callring.ai/api/v1 Bearer auth JSON Overview
The CallRing AI API is read-only and token-authenticated. Every request is guarded by two layers: the token must be valid (authentication), and it must carry the read scope the endpoint requires (authorisation). A token can be bound to one workspace, so it only ever sees data belonging to that workspace's numbers.
Base URL
https://app.callring.ai/api/v1
Auth
Authorization: Bearer crk_…
Methods
GET only
Quickstart
Create a token with the calls.read scope,
then make your first request:
curl "https://app.callring.ai/api/v1/calls" \
-H "Authorization: Bearer crk_your_token_here" \
-H "Accept: application/json" Create a token
API tokens are created from the Dev Portal inside your dashboard. Only the account owner can create them.
- 1
Open the Dev Portal
Sign in as the account owner and go to Dev Portal → Create token. Only owners can mint API tokens.
- 2
Name it & choose a workspace
Give the token a recognisable name, then bind it to a single workspace or leave it unbound to span every number you own.
- 3
Pick read scopes
Tick the resources this token may read. Each scope maps to exactly one endpoint — grant only what you need.
- 4
Copy the token once
The plaintext crk_… token is shown a single time at creation. Store it securely — it is never displayed again.
The plaintext token starts with crk_ and is shown only once.
CallRing AI stores only a hash of it — if you lose it, create a new one.
Authentication
Send your token in the Authorization header
as a Bearer credential on every request. A missing or invalid token returns
401.
const res = await fetch("https://app.callring.ai/api/v1/calls?per_page=25", {
headers: {
Authorization: "Bearer crk_your_token_here",
Accept: "application/json",
},
});
if (!res.ok) {
throw new Error(`API error ${res.status}`);
}
const { data, meta } = await res.json();
console.log(data, meta.total); Scopes
A scope is a read permission granted at token creation. Each scope unlocks exactly one endpoint. Calling an
endpoint without its scope returns 403 —
authentication alone is not enough. Grant the least you need.
| Scope | Grants | Endpoint |
|---|---|---|
calls.read | Read calls | GET /calls |
recordings.read | Read call recordings | GET /recordings |
messages.read | Read messages | GET /messages |
numbers.read | Read numbers | GET /numbers |
sources.read | Read sources | GET /sources |
campaigns.read | Read campaigns | GET /campaigns |
Workspaces
At creation you choose whether the token is bound to a workspace. This decides which numbers — and therefore which calls, recordings, messages, sources and campaigns — the token can read. Scoping happens on the server; you don't pass a workspace id in requests.
Bound to a workspace
The token reads only data tied to that workspace's numbers. Ideal for handing a single team or client access to just their slice of activity.
Without a workspace
The token spans every number you own, across all workspaces. Best for account-wide reporting or a single integration that needs the full picture.
Requests & filters
All endpoints accept query-string filters. Paginated endpoints support
per_page (1–100, default 25) and
page.
Dates use date_from / date_to. Unknown params are ignored.
curl "https://app.callring.ai/api/v1/calls?per_page=50&direction=inbound&status=completed&date_from=2026-01-01&date_to=2026-01-31" \
-H "Authorization: Bearer crk_your_token_here" Endpoints
Six read endpoints. Each requires its matching scope. Expand a card to see its query params and every field in the response.
GET /calls calls.read
List calls received by your numbers.
Query params
-
searchMatch against caller / callee number. -
directioninbound. -
statusFilter by call status (e.g. completed). -
date_fromISO date lower bound (e.g. 2026-01-01). -
date_toISO date upper bound (e.g. 2026-01-31). -
per_pageResults per page, 1–100. Default 25. -
pagePage number to fetch. Default 1.
Response fields
cr_call_id | string | Opaque id, e.g. cr_call_1842. |
cr_call_sid | string|null | Carrier call SID. |
cr_from_number | string|null | Caller number. |
cr_to_number | string|null | Destination number. |
cr_direction | string|null | inbound. |
cr_status | string|null | Call status. |
cr_duration_seconds | integer | Talk time in seconds. |
cr_price | string|null | Call cost. |
cr_recording_url | string|null | Recording link, if any. |
cr_started_at | string|null | ISO 8601 timestamp. |
cr_ended_at | string|null | ISO 8601 timestamp. |
cr_created_at | string|null | ISO 8601 timestamp. |
GET /recordings recordings.read
List call recordings with transcription status.
Query params
-
searchMatch against recording metadata. -
date_fromISO date lower bound (e.g. 2026-01-01). -
date_toISO date upper bound (e.g. 2026-01-31). -
per_pageResults per page, 1–100. Default 25. -
pagePage number to fetch. Default 1.
Response fields
cr_recording_id | string | Opaque id, e.g. cr_recording_90. |
cr_call_id | string|null | Parent call reference. |
cr_recording_sid | string|null | Carrier recording SID. |
cr_recording_url | string|null | Audio file link. |
cr_duration_seconds | integer | Recording length. |
cr_transcription_text | string|null | Transcript, if generated. |
cr_transcription_status | string|null | Transcription state. |
cr_created_at | string|null | ISO 8601 timestamp. |
GET /messages messages.read
List inbound and outbound text messages.
Query params
-
searchMatch against number or body. -
directioninbound or outbound. -
date_fromISO date lower bound (e.g. 2026-01-01). -
date_toISO date upper bound (e.g. 2026-01-31). -
per_pageResults per page, 1–100. Default 25. -
pagePage number to fetch. Default 1.
Response fields
cr_message_id | string | Opaque id, e.g. cr_message_51. |
cr_message_sid | string|null | Carrier message SID. |
cr_from_number | string|null | Sender number. |
cr_to_number | string|null | Recipient number. |
cr_direction | string|null | inbound / outbound. |
cr_body | string|null | Message text. |
cr_status | string|null | Delivery status. |
cr_price | string|null | Message cost. |
cr_sent_at | string|null | ISO 8601 timestamp. |
cr_read_at | string|null | ISO 8601 timestamp. |
cr_created_at | string|null | ISO 8601 timestamp. |
GET /numbers numbers.read
List the phone numbers on your account.
Query params
-
searchMatch against number or label. -
statusFilter by number status. -
typeFilter by number type. -
date_fromISO date lower bound (e.g. 2026-01-01). -
date_toISO date upper bound (e.g. 2026-01-31). -
per_pageResults per page, 1–100. Default 25. -
pagePage number to fetch. Default 1.
Response fields
cr_number_id | string | Opaque id, e.g. cr_number_12. |
cr_number | string|null | E.164 number. |
cr_formatted_number | string|null | Display-formatted number. |
cr_label | string|null | Friendly label. |
cr_type | string|null | Number type. |
cr_country_code | string|null | ISO country code. |
cr_status | string|null | Number status. |
cr_created_at | string|null | ISO 8601 timestamp. |
GET /sources sources.read not paginated
List all lead sources. Returned as a full list, not paginated.
Query params
-
searchMatch against name or slug. -
statusFilter by source status. -
typeFilter by source type. -
date_fromISO date lower bound (e.g. 2026-01-01). -
date_toISO date upper bound (e.g. 2026-01-31).
Response fields
cr_source_id | string | Opaque id, e.g. cr_source_7. |
cr_name | string|null | Source name. |
cr_slug | string|null | URL-safe slug. |
cr_description | string|null | Description. |
cr_type | string|null | Source type. |
cr_color | string|null | Display colour. |
cr_status | string|null | Source status. |
cr_created_at | string|null | ISO 8601 timestamp. |
GET /campaigns campaigns.read
List campaigns, each linked back to its source.
Query params
-
searchMatch against name or slug. -
statusFilter by campaign status. -
source_idInternal source id to filter by. -
date_fromISO date lower bound (e.g. 2026-01-01). -
date_toISO date upper bound (e.g. 2026-01-31). -
per_pageResults per page, 1–100. Default 25. -
pagePage number to fetch. Default 1.
Response fields
cr_campaign_id | string | Opaque id, e.g. cr_campaign_4. |
cr_source_id | string|null | Parent source reference. |
cr_name | string|null | Campaign name. |
cr_slug | string|null | URL-safe slug. |
cr_description | string|null | Description. |
cr_budget | string|null | Campaign budget. |
cr_status | string|null | Campaign status. |
cr_created_at | string|null | ISO 8601 timestamp. |
Response format
Every response is a JSON object with a data array and a
meta block. Ids are opaque and prefixed
(cr_call_1842), and every field name carries the cr_ signature — the internal database schema is never exposed.
Paginated meta includes current_page, per_page, last_page and total; the
/sources endpoint returns the full list with just total.
{
"data": [
{
"cr_call_id": "cr_call_1842",
"cr_call_sid": "CA9f2a1b7c...",
"cr_from_number": "+14155550132",
"cr_to_number": "+14155550170",
"cr_direction": "inbound",
"cr_status": "completed",
"cr_duration_seconds": 252,
"cr_price": "0.0170",
"cr_recording_url": "https://.../rec/8f2a.mp3",
"cr_started_at": "2026-01-14T09:12:04+00:00",
"cr_ended_at": "2026-01-14T09:16:16+00:00",
"cr_created_at": "2026-01-14T09:12:04+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"last_page": 8,
"total": 187
}
} Errors
Errors return a JSON message with the matching HTTP status.
HTTP/1.1 401 Unauthorized
{ "message": "The provided API token is invalid." } HTTP/1.1 403 Forbidden
{ "message": "This token is missing the required scope: calls.read." } Ready to build?
At launch, create a scoped API token in the Dev Portal and start reading your CallRing AI data in minutes. Join the waitlist for free early access.