Buying numbers

Search the carrier's stock, buy a tracking number from the console or the API, understand what it costs and what each status means, and take one out of service safely.

After this page you can find a number in the area code you want, buy it without any risk of buying it twice, read what the inventory list is telling you about it, and take one out of service when a campaign ends.

A tracking number is a phone number you rent through the platform. Callers dial it, and which number they dialled is how a call is tied to a campaign and a source. Numbers live under Numbers in the console, and every screen there works against the same two endpoints below.

Search, then buy

  1. 1

    Search the carrier's stock

    Filter by area code, by digits the number must contain, or by how it starts or ends. Results are numbers available at that moment; nothing is held for you until you buy.

    curl
    curl -X POST "https://api.buy3.io/api/tracking/numbers/search" \
      -H "Authorization: Bearer $BUY3_SESSION_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{ "areaCode": "214", "numberType": "local", "limit": 20 }'
    200 — trimmed
    {
      "results": [
        {
          "e164": "+12145550142",
          "formatted": "(214) 555-0142",
          "type": "local",
          "countryCode": "US",
          "region": "TX",
          "locality": "Dallas",
          "capabilities": { "voice": true, "sms": true, "mms": false },
          "quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
        }
      ],
      "meta": { "total": 143, "bestEffort": false }
    }

    Each result also carries setupCents and monthlyCents, and the answer repeats the platform's tariff once under price, so a form can say what a number costs before anybody has searched. The figures themselves are on the pricing page.

  2. 2

    Buy one

    Send back the quoteToken from the result you chose, along with a requestId you generate. The token names the number and the price and is refused if it does not match what you are buying, so nobody can be charged for something other than what they saw.

    curl
    curl -X POST "https://api.buy3.io/api/tracking/numbers/purchase" \
      -H "Authorization: Bearer $BUY3_SESSION_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "e164": "+12145550142",
        "quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
        "requestId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "label": "Dallas radio — morning drive",
        "tags": ["placement=radio", "region=north"]
      }'
    201 — the carrier confirmed
    {
      "order": {
        "id": "8d1f2e3a-4b5c-4d6e-9f0a-1b2c3d4e5f60",
        "e164": "+12145550142",
        "status": "completed",
        "error": null,
        "createdAt": "2026-09-20T14:03:11.000Z"
      },
      "number": {
        "id": "2f6b8c1d-4e5a-4b7c-9d8e-0f1a2b3c4d5e",
        "e164": "+12145550142",
        "formatted": "(214) 555-0142",
        "national": "(214) 555-0142",
        "type": "local",
        "status": "active",
        "role": "unassigned",
        "label": "Dallas radio — morning drive",
        "region": "TX",
        "locality": "Dallas",
        "campaign": null,
        "publisher": null,
        "pool": null,
        "webhookStatus": "ok",
        "webhookError": null,
        "renewsAt": "2026-10-20T14:03:11.000Z",
        "purchasedAt": "2026-09-20T14:03:11.000Z",
        "calls30d": 0,
        "lastCallAt": null
      }
    }
  3. 3

    Assign it

    A number lands unassigned and takes no calls until it points at a campaign. Deciding what a number is for is a separate act on purpose: conflating the two is how a number ends up quietly pointed at the wrong campaign. See Assigning numbers.

StatusMeaning
201The order completed. The number is yours and is in the response.
202The order is with the carrier and has not landed yet. number is null; the order id is how you follow it.
422The order failed. error says why, and nothing was charged.
requestId makes a retry safe: repeating a purchase with the same id finds the order already under way instead of buying a second number.

What a number costs

A number has a setup fee when you buy it and rent every month afterwards, both taken from the workspace wallet. Rent is charged whether the number is on a campaign or sitting unassigned. Calls to the number are charged separately, as connected minutes. Every figure is on the pricing page, and the console shows the exact amounts before you confirm — the What this costs panel gives your wallet balance now, what is charged today, the rent from now on, and what the wallet holds afterwards.

How many numbers a workspace may hold depends on its plan. The console warns at the limit with You are at your plan's number limit, and a purchase over it is refused. Numbers still being ordered count towards the limit as well, so a handful of clicks in the same second cannot slip past it.

What the inventory list tells you

Numbers opens on four figures — Numbers held, Unassigned, Matching this view and Rent on this page — and an Inventory table.

ColumnWhat it shows
NumberThe number as a North American reader expects to see it, with your label underneath.
Typelocal, toll_free or whatever the carrier calls it.
StatusSee the table below.
Campaign, Publisher, PoolIts three assignments. Empty means it has none.
RentWhat this one costs a month.
Calls, 30dCalls it has taken in the last thirty days.
Last callWhen it last rang.
StatusMeaning
activeIn service.
past_dueA renewal could not be paid. Top up the wallet.
suspendedNot taking calls. Support can say why.
releasedGone back to the carrier. Its past calls stay in your reports.
draftRecorded but not yet provisioned.

Labels and tags

A label is your own words for a number. It is what the inventory list sorts and searches on, and it arrives on every call the number takes as the tag number_label, so a report can group by it.

Tags are set when you buy the number and are free-text labels. One written key=value or key:value becomes a tag of its own on each call — placement=radio arrives as placement. Anything without a separator rides along together under number_tags. All of them carry the source number, which is how a filter can tell a fact about the number from a value a visitor's URL carried.

Taking a number out of service

Out of service stops a number immediately: it comes off its campaign, leaves any pool and stops routing. It does not hand the digits back to the carrier, and the rent keeps being charged. The response says so in words, and the request is on your activity log where staff pick it up.

Giving the digits back is irreversible and is completed by platform staff after somebody has looked, because a tracking workspace holds numbers printed on other people's media. Contact support to finish it. This is one of the few actions that stays open to a workspace whose subscription has lapsed — an account that has stopped paying must still be able to ask to stop being charged.

A worked example

Acme Health are about to run three placements in Dallas and want each one measured separately.

  1. Search area code 214, twenty results. Three numbers look fine.
  2. Buy all three, each with its own requestId and a label naming the placement: Dallas radio — morning drive, Dallas radio — drive home, Dallas print — weekly. Tag each with placement=radio or placement=print.
  3. Check the wallet panel before confirming: three setup fees today, three lots of rent from now on, and the balance that leaves.
  4. Assign all three to the Acme Health inbound campaign, with no publisher — this is the workspace's own media.
  5. A month later, group a report by number. The morning placement took four times the calls of the print one, so the print number goes Out of service and the rent stops at the end of the period already paid for.

Next steps