Skip to main content
A campaign that rings everyone from one number gets that number flagged as spam, and answers fall. This recipe builds the alternative: several of your own numbers in a pool, a campaign that calls from the pool at a human pace, and a way to see and react when a number stops getting answered. It suits renewals, reminders, winbacks and any outbound list that runs for more than a day.

What you’ll build

  • A pool of three or four numbers, set to 60 calls an hour each.
  • A campaign that calls from the pool, with a capacity line that tells you whether the pool can keep up.
  • A webhook that tells your backend when a number rests or the pool runs short.
  • A routine for what to do when a number rests, cools or gets retired.
You need an enabled workspace with wallet balance, a published agent, a contact list, and your API key. If your workspace has no numbers of its own yet, step 1 gets you some.

How it works

The pool counts attempts and answers on each number, in India time, across every campaign and API call that uses it. A number that has been answered less than half as often as the pool’s average, after at least 25 attempts, rests for 45 minutes and the pool keeps calling from the others. See Phone numbers and pools for every rule.

Step 1: Get your numbers

You can rent numbers through Mirai or import numbers you own. Both need a few minutes in the console and are covered in Receive inbound phone calls. For this recipe you do not assign an agent to answer, unless you also want the numbers to take incoming calls.
  1. Open Phone numbers → Numbers.
  2. Click Add a number to rent one, or Import a number for one you own.
  3. Repeat until you have the numbers you want. A pool of three or four is a good start.
A new number is Warming up for its first 7 days. It calls at half the pool’s pace until then, so it eases in. Check what you have:
Only numbers with state: "ready" on a verified connection, inside their rental term, can join a pool.
Promotional calls from regular mobile numbers can be flagged more often than calls from a number series meant for them. We do not sell that series yet. Keep promotional lists small and watch each number’s answer rate.

Step 2: Make a pool

In the console

  1. Open Phone numbers → Pools and click New pool.
  2. Give it a name and a purpose. Outreach and Reminders start at 60 an hour. Support starts at 40.
  3. Tick the numbers. Each shows its status word and its 7 day answer rate. Retired numbers cannot join.
  4. Set the pace. The line under the control reads like 3 numbers × 60 = 180 attempts an hour. Above 60 it warns that a number is more likely to be flagged as spam and answered less. Above 120 it tells you most sales desks never run this fast and numbers will rest often.
  5. Open Advanced if you want to change retries from the same number, automatic resting, the smallest number of healthy numbers the pool wants, or whether this is the default pool for new campaigns.
  6. Click Create.

With the API

The answer is 201 with the pool, its members and their health. Keep the id. A pool needs at least one member that can call now. If you get invalid_request, error.message names the number to fix.

Step 3: Point a campaign at the pool

In the console

In the campaign form, open Calls come from. The list shows your pools first, then your numbers with how each is doing, and last the Mirai shared line. Pick the pool. When you choose nothing, the campaign uses its agent’s choice, then your workspace’s default pool, then the shared line, and the form says which one it used. Under the picker, read the capacity line. It compares what the campaign will try with what the pool can carry. If Calls at once is higher than the pool can keep up with, it suggests a lower number.

With the API

Send pool_id when you create the campaign. See Campaigns for the other fields.
The campaign object answers with pool_id and a calls_from object:
Start the campaign with POST /v2/campaigns/{id}/start. A campaign calls from one source at a time. Sending pool_id together with phone_number_id or caller_ids answers 400 invalid_request. With max_concurrent: 2 and calls that last about 40 seconds, the campaign tries at most 180 times an hour, and three numbers at 60 can carry exactly that. Raise max_concurrent to 4 and the campaign would try 360, double what the pool can carry. The pool then holds contacts back for the next free number, so the campaign takes longer rather than calling faster.

Step 4: Watch health

In the console

Phone numbers → Numbers shows each number with a status word, its attempts this hour against its pace, and a 7 day answer rate with seven small bars. A day without calls is a gap. Phone numbers → Pools shows each pool with its size, how many numbers are healthy and resting, its pace and its answer rate. Open a pool to see its health first, with a 30 day chart and each number below it. The status words are Live, Warming up, Resting, Cooling and Retired. They are explained in Phone numbers and pools.

With the API

For one number’s last 30 days and today’s hours, use GET /v2/phone-numbers/{id}/health.

Be told when something changes

The campaign’s webhook_url receives phone_number.rested, phone_number.cooling, phone_number.alert, phone_number.resumed and phone_pool.degraded, signed like every other webhook. Each one carries the full number or pool and a reason written for people. Only campaigns that are running or paused and use the pool, or a number in it, get them. A pool that no campaign uses does not send events. A small handler is enough to start. Verify the signature first, as described in Webhooks.

When a number rests

A resting number is the pool working as intended. It rested because people were answering it far less than the pool’s other numbers.
  1. Check the other numbers. If the pool is healthy, do nothing. The number comes back by itself in 45 minutes.
  2. Look at the number’s 7 day answer rate. If it was already falling before it rested, the number is probably being flagged. Lower the pool’s pace or add numbers, and retire this number if its rate keeps falling.
  3. If the number rested three times in a day, it is Cooling for 7 hours and stays out until you resume it. Let it cool. Resume it early only when you have a reason, such as a list that looked cold rather than a number that looked burnt.
  4. A pool with fewer healthy numbers than its min_healthy is degraded. Add a number to it, or resume one.
To rest, resume or retire a number yourself, use the row’s Rest… or Resume action in Phone numbers → Numbers. Each leaves a notice with Undo. Through the API:
A retired number takes no outbound calls and still rings your agent when someone calls it. Resume brings it back.

Test it

Use a short list and a low pace so every behaviour shows within a few minutes.
  1. Make a pool of two numbers with max_per_hour: 6, max_per_day: 400, and min_healthy: 2.
  2. Create a campaign on it with a list of 20 numbers you can reach, then start it.
  3. Open Phone numbers → Numbers. Each number’s attempts this hour should stop at 6, and the campaign should wait for the next hour. A number added in the last 7 days is warming up and stops at half the pace, so expect 3.
  4. Rest one number for an hour. Calls continue from the other, and the rested number shows Resting with the time it is back.
  5. Resume it, then check that phone_pool.degraded reached your webhook while it was resting, because the pool wanted two healthy numbers and had one.

Privacy and compliance

Calling lists carry people’s phone numbers and often their names. Keep contact lists, transcripts and recordings behind your own access controls, and apply your retention rules. Follow the calling rules for your market, such as the do-not-call registry in India and consent requirements. Keep your do-not-call list up to date. The pace of a pool changes how many calls go out, and it does not change what you are allowed to call. A pool does not make a campaign compliant. Tell people they are speaking with an AI voice agent, and give recording notices where they apply. Each person sees the number they are called from, so use numbers that you can answer when they call back, and point those numbers at an agent.

Production checklist

  • Each number you rely on is ready, and its rental is in term.
  • The pool’s pace is at or below 60 an hour unless you have chosen otherwise, and the capacity line shows it can carry the campaign’s calls at once.
  • min_healthy matches the number of numbers you need to run.
  • The campaign’s webhook_url verifies signatures, dedupes on id, and tells a person when a pool is degraded.
  • Someone knows what to do when a number cools, and who can resume or retire it.
  • You have a default pool or an agent calls_from, so a campaign never falls to the shared line by accident.

Phone numbers and pools

Every field, health state, event and error code.

Campaigns

Calling windows, retries, budget and the report.

Webhooks

Verify signatures and handle retries.

Receive inbound phone calls

Rent or import a number and make it answer.