API reference
Pools and DNI
Create and manage number pools for dynamic number insertion, fetch a pool's snippet and read its visitor sessions.
A number pool shares a set of tracking numbers among the visitors to a website, so that when one of those numbers rings you know which visit — and which ad, keyword or click id — produced the call. This group creates and manages pools. The two requests the snippet makes from a visitor's browser are in DNI public endpoints, and the walkthrough is in Number pools and DNI.
A console surface
Every endpoint on this page is the console's own, under /api/tracking. It is called with the session token of a signed-in owner or admin of the workspace, sent as Authorization: Bearer <token>. No API-key scope opens a pool: a key cannot list, create or change one. Pools are set up by a person, once, and then run by themselves.
https://api.buy3.io/api/tracking- Every request may carry an optional
agencyId(a UUID, in the query string or the body). Leave it out when you administer one workspace. Send it when you administer several — without it the answer is400withdetails.agencyIdlisting the ones you could mean. - A write needs an active subscription. A read does not: a lapsed workspace can still see everything it owns.
- Every write here is recorded in the activity log under the kind
pool, with the values before and after.
What you can do
| Operation | Notes |
|---|---|
| List and create pools | A pool belongs to one campaign for life, and is given a public key when it is created. |
| Read, update and delete a pool | Deleting a pool never deletes numbers: they go back to being static tracking numbers on the same campaign. |
| Get the snippet | The <script> tag to paste into your site, with the pool's public key already in it. |
| List sessions | Who is holding the pool's numbers now, and who was: the number each visitor leased and the URL parameters that were captured. |
poolId.The pool object
| Field | Type | Meaning |
|---|---|---|
id | uuid | The pool's id. |
name | string | Your name for it. |
status | string | active or paused. |
publicKey | string | pk_ and 24 hex characters. It is public by design — see below. |
campaign | object | { id, name, status } — the campaign every number in the pool points at. |
publisher | object | null | { id, name }, or null for your own media. |
sessionTtlSeconds | integer | How long a lease lasts without a heartbeat. |
allowedDomains | string[] | Bare hosts. An empty list means any website. |
captureParams | string[] | The URL parameters that become tags. |
fallbackNumber | object | null | { id, e164, formatted }. |
health | object | { numbers, activeSessions, overflow24h, saturated, warning } — see Pool health. |
createdAt, updatedAt | ISO 8601 | When the pool was made and last changed. |
Pool health
A pool does its job only while it has a spare number for the next visitor. health says whether it does, on every read of a pool.
| Field | Meaning |
|---|---|
numbers | Active tracking numbers rotating in the pool. |
activeSessions | Visitors holding a lease right now. |
overflow24h | Visitors in the last 24 hours who could not be given a number of their own: they shared one, or saw the fallback. |
saturated | true when the pool has numbers and activeSessions has reached numbers. The next visitor will share a number or see the fallback. |
warning | A sentence for a person when the pool has no numbers, is saturated or overflowed in the last day. Otherwise null. |
The session object
| Field | Type | Meaning |
|---|---|---|
id | string | A large integer, sent as a string. |
visitorId | string | The random id the snippet keeps in the visitor's browser. |
number | object | null | { id, e164, formatted } — the number the visitor was shown. |
params | object | The captured URL parameters. They become the call's tags, with the source dni. |
landingUrl, referrer | string | null | As the snippet reported them, cut at 2,000 characters. |
ip, userAgent | string | null | The visitor's address and browser. They are your own site's traffic, so they are yours to read. |
startedAt, lastSeenAt, expiresAt | ISO 8601 | The lease's life. Every heartbeat moves lastSeenAt and expiresAt forward. |
active | boolean | The lease is live now. |
fallback | boolean | The visitor was shown the fallback number. Nothing was leased, and no call can be tied to the visit. |
overflow | boolean | The visitor was given a number another visitor still held, or the fallback. Attribution is best effort. |
callId | uuid | null | The first call this lease produced. |
The public key
A pool's public key is meant to be published: it sits in your page's source for anybody to read. All it can do is lease a number from its own pool, and the lease endpoints are rate limited and can be tied to your domains. It is not an API key, grants no access to your data, and is the only credential that should ever appear in a web page.
Endpoints
- GET
/api/tracking/poolsList pools - POST
/api/tracking/poolsCreate a pool - GET
/api/tracking/pools/:idRead a pool - PATCH
/api/tracking/pools/:idUpdate a pool - DELETE
/api/tracking/pools/:idDelete a pool - GET
/api/tracking/pools/:id/snippetGet the snippet - GET
/api/tracking/pools/:id/sessionsList sessions
List pools
/api/tracking/poolsThe workspace's pools, each with its health, so one request answers which pool is running out of numbers. Changes nothing.
Query parameters
| Name | Type | Description |
|---|---|---|
qOptional | string | Matches part of the pool's name, ignoring case.up to 80 characters |
statusOptional | string | Only pools in this state.active or paused |
campaignIdOptional | uuid | Only pools on this campaign. |
publisherIdOptional | uuid | Only pools attributed to this publisher. |
pageOptional | integer | The page to return.from 1, default 1 |
pageSizeOptional | integer | Rows per page. A larger value is clamped, not refused.1–200 · default 25 |
sortOptional | string | The field to sort by. Anything else falls back to the default.createdAt, name or status · default createdAt |
dirOptional | string | Sort direction.asc or desc · default desc |
Example request
curl "https://api.buy3.io/api/tracking/pools?status=active&pageSize=50" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN"Responses
- 200One page of pools in the standard list envelope.
{
"data": [
{
"id": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
"name": "Medicare landing pages",
"status": "active",
"publicKey": "pk_3f9a1c2b7d8e4f60a1b2c3d4",
"campaign": {
"id": "6a2d1f0e-8b7c-4c55-a1d3-0e9f8a7b6c5d",
"name": "Medicare — Inbound",
"status": "live"
},
"publisher": null,
"sessionTtlSeconds": 1800,
"allowedDomains": [
"example.com"
],
"captureParams": [
"gclid",
"utm_*"
],
"fallbackNumber": {
"id": "b7c6d5e4-f3a2-4b1c-8d9e-0a1b2c3d4e5f",
"e164": "+18885550100",
"formatted": "(888) 555-0100"
},
"health": {
"numbers": 8,
"activeSessions": 3,
"overflow24h": 0,
"saturated": false,
"warning": null
},
"createdAt": "2026-09-12T09:30:00.000Z",
"updatedAt": "2026-09-18T16:04:21.000Z"
}
],
"page": 1,
"pageSize": 25,
"total": 1,
"totalPages": 1
}Errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | status is not a pool status, or campaignId or publisherId is not a UUID. |
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | An agencyId that is not a workspace you administer answers the same 404. |
Create a pool
/api/tracking/poolsCreates a pool on one campaign and mints its public key. The pool starts with no numbers: assign tracking numbers to it through the Numbers API before you install the snippet. Recorded in the activity log (pool, medium severity). It costs nothing in itself — the numbers you put in it are rented as any number is.
Request body
| Name | Type | Description |
|---|---|---|
nameRequired | string | Your name for the pool.1–120 characters |
campaignIdRequired | uuid | The tracking campaign the pool feeds. It must be yours and not archived. It cannot be changed later. |
publisherIdOptional | uuid | null | The publisher the pool's calls are attributed to. It must be a publisher of yours with a lane on the pool's campaign. null means your own media.default null |
sessionTtlSecondsOptional | integer | How long a visitor keeps their number after the last heartbeat. Short leases free numbers sooner; long ones survive a visitor who reads the page before calling.60–86400 · default 1800 |
allowedDomainsOptional | string[] | The websites allowed to lease from the pool. An entry is reduced to a bare host — https://www.example.com/landing is stored as www.example.com — and covers its subdomains. An empty list lets any website lease.at most 50 entries of up to 260 characters · default [] |
captureParamsOptional | string[] | The URL parameters kept from a visitor's landing page and copied onto their call as tags. Anything not listed is dropped, so a query string that carries an email address never reaches a call record. A trailing * is a prefix rule: utm_* keeps every utm_ parameter. A bare * is refused.at most 40 entries of up to 65 characters · letters, digits, _, . and -, stored in lower case · default utm_source, utm_medium, utm_campaign, utm_term, utm_content, gclid, fbclid and msclkid |
fallbackNumberIdOptional | uuid | null | The number shown when every number in the pool is held. It must be an in-service tracking number on the pool's campaign that is not in a pool itself.default null |
statusOptional | string | A paused pool leases nothing: the snippet leaves each page's own number in place, and live leases stop extending.active or paused · default active |
Example request
curl -X POST "https://api.buy3.io/api/tracking/pools" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Medicare landing pages",
"campaignId": "6a2d1f0e-8b7c-4c55-a1d3-0e9f8a7b6c5d",
"sessionTtlSeconds": 1800,
"allowedDomains": ["example.com"],
"captureParams": ["gclid", "utm_*"]
}'Responses
- 201The pool, with its new
publicKeyand its health (all zeroes until numbers join).
{
"pool": {
"id": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
"name": "Medicare landing pages",
"status": "active",
"publicKey": "pk_3f9a1c2b7d8e4f60a1b2c3d4",
"campaign": {
"id": "6a2d1f0e-8b7c-4c55-a1d3-0e9f8a7b6c5d",
"name": "Medicare — Inbound",
"status": "live"
},
"publisher": null,
"sessionTtlSeconds": 1800,
"allowedDomains": [
"example.com"
],
"captureParams": [
"gclid",
"utm_*"
],
"fallbackNumber": null,
"health": {
"numbers": 0,
"activeSessions": 0,
"overflow24h": 0,
"saturated": false,
"warning": "No active number is in this pool, so the snippet leaves each page's own number in place. Assign tracking numbers to the pool."
},
"createdAt": "2026-09-12T09:30:00.000Z",
"updatedAt": "2026-09-12T09:30:00.000Z"
}
}Errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | A field is missing, has the wrong type or is out of range. details maps each field to what was wrong with it. |
| 400 | bad_request | An allowedDomains entry is not a hostname, or a captureParams entry is not a parameter name. details names up to five of the bad entries. |
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | subscription_inactive | The workspace's subscription is not active. Reads stay open to a lapsed workspace; writes do not. details carries status, planId and agencyId. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | The campaign, the publisher or the fallback number is not in the workspace, or the campaign is not a tracking campaign. Somebody else's record answers exactly as a missing one does. An agencyId that is not a workspace you administer answers the same 404. |
| 409 | conflict | The campaign is archived, or the fallback number has been released back to the carrier. |
| 409 | publisher_not_on_campaign | The publisher has no lane on the pool's campaign. Add them to the campaign first, so their payout terms exist before their calls do. details carries publisherId and campaignId. |
| 409 | fallback_wrong_campaign | The fallback is not a tracking number on the pool's campaign. details.numberId names it. |
| 409 | fallback_in_pool | The fallback is rotating in a pool. A fallback has to be a static number. details carries numberId and poolId. |
Read a pool
/api/tracking/pools/:idOne pool with its health, and the numbers rotating in it — ordered by number, each with its call count for the last 30 days. Each is the number object the Numbers API documents; the example below leaves out its rent fields.
Path parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The pool's id. |
Example request
curl "https://api.buy3.io/api/tracking/pools/2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN"Responses
- 200The pool and its numbers.
{
"pool": {
"id": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
"name": "Medicare landing pages",
"status": "active",
"publicKey": "pk_3f9a1c2b7d8e4f60a1b2c3d4",
"campaign": {
"id": "6a2d1f0e-8b7c-4c55-a1d3-0e9f8a7b6c5d",
"name": "Medicare — Inbound",
"status": "live"
},
"publisher": null,
"sessionTtlSeconds": 1800,
"allowedDomains": [
"example.com"
],
"captureParams": [
"gclid",
"utm_*"
],
"fallbackNumber": {
"id": "b7c6d5e4-f3a2-4b1c-8d9e-0a1b2c3d4e5f",
"e164": "+18885550100",
"formatted": "(888) 555-0100"
},
"health": {
"numbers": 8,
"activeSessions": 3,
"overflow24h": 0,
"saturated": false,
"warning": null
},
"createdAt": "2026-09-12T09:30:00.000Z",
"updatedAt": "2026-09-18T16:04:21.000Z"
},
"numbers": [
{
"id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
"e164": "+16195550134",
"formatted": "(619) 555-0134",
"national": "(619) 555-0134",
"type": "local",
"status": "active",
"role": "tracking",
"label": null,
"region": "CA",
"locality": "San Diego",
"campaign": {
"id": "6a2d1f0e-8b7c-4c55-a1d3-0e9f8a7b6c5d",
"name": "Medicare — Inbound",
"status": "live"
},
"publisher": null,
"pool": {
"id": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
"name": "Medicare landing pages"
},
"webhookStatus": "active",
"webhookError": null,
"purchasedAt": "2026-09-12T09:12:40.000Z",
"calls30d": 41,
"lastCallAt": "2026-09-20T13:47:02.000Z"
}
]
}Errors
| Status | Code | When |
|---|---|---|
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | No such pool in the workspace. Somebody else's pool and an id that is not a UUID answer exactly as a missing one does. An agencyId that is not a workspace you administer answers the same 404. |
Update a pool
/api/tracking/pools/:idChanges any setting except the campaign. Send only the fields you want to change. Changing publisherId re-attributes every number in the pool in the same transaction, so a pool's calls are never split between the old source and the new one. Recorded in the activity log (pool) — high severity when status or allowedDomains changes, because pausing stops number insertion on a live site and opening the domain list lets any page lease.
Path parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The pool's id. |
Request body
| Name | Type | Description |
|---|---|---|
nameOptional | string | A new name.1–120 characters |
publisherIdOptional | uuid | null | The publisher the pool's calls are attributed to. It must be a publisher of yours with a lane on the pool's campaign. null means your own media.default null |
sessionTtlSecondsOptional | integer | How long a visitor keeps their number after the last heartbeat. Short leases free numbers sooner; long ones survive a visitor who reads the page before calling.60–86400 · default 1800 |
allowedDomainsOptional | string[] | The websites allowed to lease from the pool. An entry is reduced to a bare host — https://www.example.com/landing is stored as www.example.com — and covers its subdomains. An empty list lets any website lease.at most 50 entries of up to 260 characters · default [] |
captureParamsOptional | string[] | The URL parameters kept from a visitor's landing page and copied onto their call as tags. Anything not listed is dropped, so a query string that carries an email address never reaches a call record. A trailing * is a prefix rule: utm_* keeps every utm_ parameter. A bare * is refused.at most 40 entries of up to 65 characters · letters, digits, _, . and -, stored in lower case · default utm_source, utm_medium, utm_campaign, utm_term, utm_content, gclid, fbclid and msclkid |
fallbackNumberIdOptional | uuid | null | The number shown when every number in the pool is held. It must be an in-service tracking number on the pool's campaign that is not in a pool itself.default null |
statusOptional | string | A paused pool leases nothing: the snippet leaves each page's own number in place, and live leases stop extending.active or paused · default active |
Example request
curl -X PATCH "https://api.buy3.io/api/tracking/pools/2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "paused"
}'Responses
- 200The pool as it now stands.
{
"pool": {
"id": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
"name": "Medicare landing pages",
"status": "paused",
"publicKey": "pk_3f9a1c2b7d8e4f60a1b2c3d4",
"campaign": {
"id": "6a2d1f0e-8b7c-4c55-a1d3-0e9f8a7b6c5d",
"name": "Medicare — Inbound",
"status": "live"
},
"publisher": null,
"sessionTtlSeconds": 1800,
"allowedDomains": [
"example.com"
],
"captureParams": [
"gclid",
"utm_*"
],
"fallbackNumber": {
"id": "b7c6d5e4-f3a2-4b1c-8d9e-0a1b2c3d4e5f",
"e164": "+18885550100",
"formatted": "(888) 555-0100"
},
"health": {
"numbers": 8,
"activeSessions": 3,
"overflow24h": 0,
"saturated": false,
"warning": null
},
"createdAt": "2026-09-12T09:30:00.000Z",
"updatedAt": "2026-09-20T15:10:44.000Z"
}
}Errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | A field has the wrong type or is out of range. details maps each field to what was wrong with it. |
| 400 | bad_request | The body names no field to change (Nothing to update). An allowedDomains entry is not a hostname, or a captureParams entry is not a parameter name. details names up to five of the bad entries. |
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | subscription_inactive | The workspace's subscription is not active. Reads stay open to a lapsed workspace; writes do not. details carries status, planId and agencyId. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | No such pool in the workspace. Somebody else's pool and an id that is not a UUID answer exactly as a missing one does. So does a publisherId or fallbackNumberId that is not in the workspace. An agencyId that is not a workspace you administer answers the same 404. |
| 409 | conflict | The new fallback number has been released back to the carrier. |
| 409 | pool_campaign_fixed | The body names a different campaignId. A pool cannot move: create a pool on the other campaign and move the numbers into it. |
| 409 | publisher_not_on_campaign | The publisher has no lane on the pool's campaign. Add them to the campaign first, so their payout terms exist before their calls do. details carries publisherId and campaignId. |
| 409 | fallback_wrong_campaign | The fallback is not a tracking number on the pool's campaign. details.numberId names it. |
| 409 | fallback_in_pool | The fallback is rotating in a pool. A fallback has to be a static number. details carries numberId and poolId. |
Delete a pool
/api/tracking/pools/:idDeletes the pool and its sessions. It never deletes numbers: they return to being static tracking numbers on the same campaign, still rented and still ringing. Calls already made keep their tags. What you lose is per-visitor attribution on any page that still carries the snippet, which is why the answer counts the visitors who were holding a lease. Recorded in the activity log (pool, high severity).
Path parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The pool's id. |
Example request
curl -X DELETE "https://api.buy3.io/api/tracking/pools/2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN"Responses
- 200The id that was deleted, how many numbers went back to being static, and how many visitors held a lease at that moment.
{
"deleted": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
"numbersReturned": 8,
"activeSessions": 3
}Errors
| Status | Code | When |
|---|---|---|
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | subscription_inactive | The workspace's subscription is not active. Reads stay open to a lapsed workspace; writes do not. details carries status, planId and agencyId. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | No such pool in the workspace. Somebody else's pool and an id that is not a UUID answer exactly as a missing one does. An agencyId that is not a workspace you administer answers the same 404. |
Get the snippet
/api/tracking/pools/:id/snippetEverything the pool's install screen shows: the <script> tag with the pool's public key in it, an example of the markup it rewrites, and the notes and warnings worth reading before you paste it. The tag is the same file for every pool — it reads its key from its own data-pool attribute. See The DNI snippet.
Path parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The pool's id. |
Query parameters
| Name | Type | Description |
|---|---|---|
swapOptional | string | The CSS selector of the elements whose number the snippet replaces. It is written into the tag's data-swap attribute.up to 120 characters: letters, digits, spaces and the punctuation a selector needs · default .b3-number |
Example request
curl "https://api.buy3.io/api/tracking/pools/2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e/snippet?swap=.phone" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN"Responses
- 200
warningsis empty for an active pool on a public address. It says so when the pool is paused, or when the script URL points at an address no visitor's browser can reach.
{
"html": "<script src=\"https://api.buy3.io/api/public/dni/b3dni.js\" data-pool=\"pk_3f9a1c2b7d8e4f60a1b2c3d4\" data-swap=\".b3-number\" async></script>",
"scriptUrl": "https://api.buy3.io/api/public/dni/b3dni.js",
"poolKey": "pk_3f9a1c2b7d8e4f60a1b2c3d4",
"swapSelector": ".b3-number",
"example": "<a class=\"b3-number\" href=\"tel:+18005550100\">(800) 555-0100</a>",
"notes": [
"Paste the tag once, anywhere in the page — before </body> is fine. It loads asynchronously and never blocks rendering.",
"If the tag cannot lease a number for any reason, it does nothing and your own number stays on the page.",
"Only pages on example.com (and their subdomains) may use this pool."
],
"warnings": []
}Errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | swap is longer than 120 characters or holds a character a CSS selector does not need. |
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | No such pool in the workspace. Somebody else's pool and an id that is not a UUID answer exactly as a missing one does. An agencyId that is not a workspace you administer answers the same 404. |
List sessions
/api/tracking/pools/:id/sessionsThe pool's DNI sessions, most recently seen first, with the pool's current health beside the page. Use it to check that parameters are being captured, and to see how often visitors overflow. Sessions that ended more than 30 days ago have been pruned; the calls they produced keep their tags.
Path parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The pool's id. |
Query parameters
| Name | Type | Description |
|---|---|---|
activeOptional | boolean | true for leases that are live now, false for ones that have ended. Leave it out for both.true or false |
pageOptional | integer | The page to return.from 1, default 1 |
pageSizeOptional | integer | Rows per page. A larger value is clamped, not refused.1–200 · default 25 |
Example request
curl "https://api.buy3.io/api/tracking/pools/2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e/sessions?active=true" \
-H "Authorization: Bearer $BUY3_SESSION_TOKEN"Responses
- 200One page of sessions, plus the pool's
health.
{
"data": [
{
"id": "48211",
"visitorId": "v_5c1e0a9b7d3f2e1c4b6a8d90",
"number": {
"id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
"e164": "+16195550134",
"formatted": "(619) 555-0134"
},
"params": {
"gclid": "Cj0KCQjw",
"utm_source": "google",
"utm_campaign": "medicare-q3"
},
"landingUrl": "https://www.example.com/medicare?gclid=Cj0KCQjw&utm_source=google&utm_campaign=medicare-q3",
"referrer": "https://www.google.com/",
"ip": "203.0.113.24",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"startedAt": "2026-09-20T14:01:07.000Z",
"lastSeenAt": "2026-09-20T14:04:07.000Z",
"expiresAt": "2026-09-20T14:34:07.000Z",
"active": true,
"fallback": false,
"overflow": false,
"callId": "0b9f6c1e-52a4-4a0e-9f0a-3d1c7e8b2a11"
}
],
"page": 1,
"pageSize": 25,
"total": 1,
"totalPages": 1,
"health": {
"numbers": 8,
"activeSessions": 3,
"overflow24h": 0,
"saturated": false,
"warning": null
}
}Errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | active is neither true nor false. |
| 401 | unauthorized | No session token, or one that has expired. |
| 402 | plan_upgrade_required | The workspace's plan does not include call tracking. details.feature is callTracking. |
| 403 | forbidden | You named no workspace and hold no owner or admin seat on any. |
| 404 | not_found | No such pool in the workspace. Somebody else's pool and an id that is not a UUID answer exactly as a missing one does. An agencyId that is not a workspace you administer answers the same 404. |
