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.

Base URL
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 is 400 with details.agencyId listing 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

OperationNotes
List and create poolsA pool belongs to one campaign for life, and is given a public key when it is created.
Read, update and delete a poolDeleting a pool never deletes numbers: they go back to being static tracking numbers on the same campaign.
Get the snippetThe <script> tag to paste into your site, with the pool's public key already in it.
List sessionsWho is holding the pool's numbers now, and who was: the number each visitor leased and the URL parameters that were captured.
Numbers join or leave a pool through the Numbers API, by setting a number's poolId.

The pool object

FieldTypeMeaning
iduuidThe pool's id.
namestringYour name for it.
statusstringactive or paused.
publicKeystringpk_ and 24 hex characters. It is public by design — see below.
campaignobject{ id, name, status } — the campaign every number in the pool points at.
publisherobject | null{ id, name }, or null for your own media.
sessionTtlSecondsintegerHow long a lease lasts without a heartbeat.
allowedDomainsstring[]Bare hosts. An empty list means any website.
captureParamsstring[]The URL parameters that become tags.
fallbackNumberobject | null{ id, e164, formatted }.
healthobject{ numbers, activeSessions, overflow24h, saturated, warning } — see Pool health.
createdAt, updatedAtISO 8601When 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.

FieldMeaning
numbersActive tracking numbers rotating in the pool.
activeSessionsVisitors holding a lease right now.
overflow24hVisitors in the last 24 hours who could not be given a number of their own: they shared one, or saw the fallback.
saturatedtrue when the pool has numbers and activeSessions has reached numbers. The next visitor will share a number or see the fallback.
warningA sentence for a person when the pool has no numbers, is saturated or overflowed in the last day. Otherwise null.

The session object

FieldTypeMeaning
idstringA large integer, sent as a string.
visitorIdstringThe random id the snippet keeps in the visitor's browser.
numberobject | null{ id, e164, formatted } — the number the visitor was shown.
paramsobjectThe captured URL parameters. They become the call's tags, with the source dni.
landingUrl, referrerstring | nullAs the snippet reported them, cut at 2,000 characters.
ip, userAgentstring | nullThe visitor's address and browser. They are your own site's traffic, so they are yours to read.
startedAt, lastSeenAt, expiresAtISO 8601The lease's life. Every heartbeat moves lastSeenAt and expiresAt forward.
activebooleanThe lease is live now.
fallbackbooleanThe visitor was shown the fallback number. Nothing was leased, and no call can be tied to the visit.
overflowbooleanThe visitor was given a number another visitor still held, or the fallback. Attribution is best effort.
callIduuid | nullThe 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

List pools

GET/api/tracking/pools

The workspace's pools, each with its health, so one request answers which pool is running out of numbers. Changes nothing.

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Query parameters

NameTypeDescription
qOptionalstringMatches part of the pool's name, ignoring case.up to 80 characters
statusOptionalstringOnly pools in this state.active or paused
campaignIdOptionaluuidOnly pools on this campaign.
publisherIdOptionaluuidOnly pools attributed to this publisher.
pageOptionalintegerThe page to return.from 1, default 1
pageSizeOptionalintegerRows per page. A larger value is clamped, not refused.1–200 · default 25
sortOptionalstringThe field to sort by. Anything else falls back to the default.createdAt, name or status · default createdAt
dirOptionalstringSort 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

StatusCodeWhen
400validation_errorstatus is not a pool status, or campaignId or publisherId is not a UUID.
401unauthorizedNo session token, or one that has expired.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundAn agencyId that is not a workspace you administer answers the same 404.

Create a pool

POST/api/tracking/pools

Creates 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.

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Request body

NameTypeDescription
nameRequiredstringYour name for the pool.1–120 characters
campaignIdRequireduuidThe tracking campaign the pool feeds. It must be yours and not archived. It cannot be changed later.
publisherIdOptionaluuid | nullThe 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
sessionTtlSecondsOptionalintegerHow 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
allowedDomainsOptionalstring[]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 []
captureParamsOptionalstring[]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
fallbackNumberIdOptionaluuid | nullThe 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
statusOptionalstringA 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 publicKey and 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

StatusCodeWhen
400validation_errorA field is missing, has the wrong type or is out of range. details maps each field to what was wrong with it.
400bad_requestAn allowedDomains entry is not a hostname, or a captureParams entry is not a parameter name. details names up to five of the bad entries.
401unauthorizedNo session token, or one that has expired.
402subscription_inactiveThe workspace's subscription is not active. Reads stay open to a lapsed workspace; writes do not. details carries status, planId and agencyId.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundThe 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.
409conflictThe campaign is archived, or the fallback number has been released back to the carrier.
409publisher_not_on_campaignThe 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.
409fallback_wrong_campaignThe fallback is not a tracking number on the pool's campaign. details.numberId names it.
409fallback_in_poolThe fallback is rotating in a pool. A fallback has to be a static number. details carries numberId and poolId.

Read a pool

GET/api/tracking/pools/:id

One 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.

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Path parameters

NameTypeDescription
idRequireduuidThe 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

StatusCodeWhen
401unauthorizedNo session token, or one that has expired.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundNo 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

PATCH/api/tracking/pools/:id

Changes 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.

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Path parameters

NameTypeDescription
idRequireduuidThe pool's id.

Request body

NameTypeDescription
nameOptionalstringA new name.1–120 characters
publisherIdOptionaluuid | nullThe 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
sessionTtlSecondsOptionalintegerHow 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
allowedDomainsOptionalstring[]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 []
captureParamsOptionalstring[]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
fallbackNumberIdOptionaluuid | nullThe 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
statusOptionalstringA 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

StatusCodeWhen
400validation_errorA field has the wrong type or is out of range. details maps each field to what was wrong with it.
400bad_requestThe 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.
401unauthorizedNo session token, or one that has expired.
402subscription_inactiveThe workspace's subscription is not active. Reads stay open to a lapsed workspace; writes do not. details carries status, planId and agencyId.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundNo 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.
409conflictThe new fallback number has been released back to the carrier.
409pool_campaign_fixedThe body names a different campaignId. A pool cannot move: create a pool on the other campaign and move the numbers into it.
409publisher_not_on_campaignThe 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.
409fallback_wrong_campaignThe fallback is not a tracking number on the pool's campaign. details.numberId names it.
409fallback_in_poolThe fallback is rotating in a pool. A fallback has to be a static number. details carries numberId and poolId.

Delete a pool

DELETE/api/tracking/pools/:id

Deletes 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).

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Path parameters

NameTypeDescription
idRequireduuidThe 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

StatusCodeWhen
401unauthorizedNo session token, or one that has expired.
402subscription_inactiveThe workspace's subscription is not active. Reads stay open to a lapsed workspace; writes do not. details carries status, planId and agencyId.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundNo 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

GET/api/tracking/pools/:id/snippet

Everything 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.

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Path parameters

NameTypeDescription
idRequireduuidThe pool's id.

Query parameters

NameTypeDescription
swapOptionalstringThe 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

  • 200warnings is 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

StatusCodeWhen
400validation_errorswap is longer than 120 characters or holds a character a CSS selector does not need.
401unauthorizedNo session token, or one that has expired.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundNo 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

GET/api/tracking/pools/:id/sessions

The 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.

Console session. Called by the console with the signed-in user's session. Use the REST API with an API key for your own integrations.

Path parameters

NameTypeDescription
idRequireduuidThe pool's id.

Query parameters

NameTypeDescription
activeOptionalbooleantrue for leases that are live now, false for ones that have ended. Leave it out for both.true or false
pageOptionalintegerThe page to return.from 1, default 1
pageSizeOptionalintegerRows 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

StatusCodeWhen
400validation_erroractive is neither true nor false.
401unauthorizedNo session token, or one that has expired.
402plan_upgrade_requiredThe workspace's plan does not include call tracking. details.feature is callTracking.
403forbiddenYou named no workspace and hold no owner or admin seat on any.
404not_foundNo 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.