For AI voice agents
Check every number before your AI voice agent dials it
Your AI voice agent dials whatever number it is handed, including numbers on Do Not Call lists and numbers that belong to known TCPA litigators.
Phone Scrub checks each number in one API call before the call is created, and returns the line type too, so your agent can skip a landline when it wants a mobile.
10 credits a check when the number is found, nothing when it is unknown.
- Your agent is about to call +1 201 555 0123
- It asks Phone Scrub first: Do Not Call, litigator, line type
- Known litigator or Do Not Call: the agent skips the call
- Clean mobile number: the agent dials
Phone Scrub answers between your agent picking a number and your server placing the call
It is one extra request in the server that already starts your calls, so nothing changes in the agent itself.
Step 1
Your agent picks the next number
It comes from your call list or your CRM, before any call is created.
Step 2
Your server asks 1Lookup Phone Scrub
One POST with the number, and one JSON answer back.
- Do Not Call?
- Litigator?
- Line type?
Skip the call
The number is on a Do Not Call list or belongs to a known litigator.
Route the number
It is clean, but a landline or VoIP line is not what your script is built for.
Dial the call
A clean number of the line type you want.
One POST request with the number returns the answer as JSON
Send the number in phone_number with your API key as a bearer token. The numbers below are made up.
The request
curl -X POST https://app.1lookup.io/api/v1/phone-scrub \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phone_number": "+12015550123"}'- Method and address
- POST https://app.1lookup.io/api/v1/phone-scrub
- Header
- Authorization: Bearer YOUR_API_KEY
- Body field
- phone_number, with or without a country code
- Cost
- 10 credits when found, 0 when unknown
Create a key in the 1Lookup app, then read the API docs for the other fields.
The response for a known litigator, trimmed to what your agent reads
{
"success": true,
"data": {
"classification": {
"matched": true,
"phoneTypeCode": "X",
"phoneTypeLabel": "LITIGATOR",
"doNotCall": false,
"litigator": true
},
"recommendations": {
"primary_action": "BLOCK",
"business_rules": {
"can_use_contact": false,
"do_not_call": false,
"litigator_risk": true
}
},
"metadata": {
"credits_used": 10,
"cache_hit": false
}
}
}Five fields in the response tell your agent what to do
A true litigator or doNotCall ends the check. The other three fields decide the rest.
litigatorTrue when the number belongs to a known litigator, serial complainer or attorney.
Skip the call every time.
doNotCallTrue when the number is on a Do Not Call list.
Skip the call.
phoneTypeLabelThe line type: MOBILE, LANDLINE, VOIP, LITIGATOR or UNKNOWN.
Dial only the line types your script is built for.
matchedFalse when 1Lookup has no record of the number. Nothing is charged.
Hold the number for review. The suggested action is REVIEW.
recommendations.business_rules. can_use_contact True only when the number matched and is neither on a Do Not Call list nor a litigator.
Gate the call on this one boolean when you want a single check.
Each kind of number comes back with a different answer
These are the four results your agent meets most, as they appear in the classification part of the response.
A clean mobile number
matched: true
phoneTypeLabel: "MOBILE"
doNotCall: false
litigator: false
primary_action: APPROVEYour agent places the call.
A landline when you want mobile
matched: true
phoneTypeLabel: "LANDLINE"
doNotCall: false
litigator: false
primary_action: APPROVEThe number is clean, so send it to a campaign built for landlines.
A number on a Do Not Call list
matched: true
phoneTypeLabel: "MOBILE"
doNotCall: true
litigator: false
primary_action: BLOCKYour agent never dials it.
A known TCPA litigator
matched: true
phoneTypeLabel: "LITIGATOR"
doNotCall: false
litigator: true
primary_action: BLOCKYour agent never dials it, whatever else the record says.
Run the check in your server right before it creates the outbound call
This is Node and TypeScript. The same function goes in front of whichever request your platform uses to create a call.
const PHONE_SCRUB = "https://app.1lookup.io/api/v1/phone-scrub";
type Verdict = { dial: boolean; reason: string };
export async function preDialCheck(
phone: string,
allowedLineTypes = ["MOBILE"],
): Promise<Verdict> {
const res = await fetch(PHONE_SCRUB, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ONELOOKUP_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ phone_number: phone }),
});
// A failed check throws, so the call is never placed.
if (!res.ok) throw new Error(`Phone Scrub returned ${res.status}`);
const { data } = await res.json();
const { matched, phoneTypeLabel, doNotCall, litigator } = data.classification;
if (litigator) return { dial: false, reason: "known litigator" };
if (doNotCall) return { dial: false, reason: "on a Do Not Call list" };
if (!matched) return { dial: false, reason: "no record, hold for review" };
if (!allowedLineTypes.includes(phoneTypeLabel)) {
return { dial: false, reason: `line type is ${phoneTypeLabel}` };
}
return { dial: true, reason: "clean number" };
}
export async function startOutboundCall(phone: string) {
const verdict = await preDialCheck(phone);
if (!verdict.dial) return { skipped: verdict.reason };
const res = await fetch("https://api.vapi.ai/call", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VAPI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
assistantId: process.env.VAPI_ASSISTANT_ID,
phoneNumberId: process.env.VAPI_PHONE_NUMBER_ID,
customer: { number: phone }, // E.164, like +12015550123
}),
});
return res.json();
}What this code does
- A litigator or Do Not Call number never reaches your voice platform.
- If the check itself fails, the function throws and no call is placed.
- Only the line types in allowedLineTypes are dialed, so a landline is never dialed by a mobile script.
The second function creates a call with the request in Vapi's create call reference. For Retell, Bland or your own Twilio stack, call preDialCheck before the request that creates the call.
A check costs 10 credits when the number is found and nothing when it is not
You pay for the answers you get. A number 1Lookup has no record of comes back with matched set to false and costs nothing.
10 credits
A number is found
Do Not Call, litigator and line type come back together.
0 credits
A number is unknown
matched is false and nothing is charged.
About $0.05
One check on the Starter plan
Larger plans cost less per credit.
- Starter$49.50
About $0.05 a check
- Growth$35.20
About $0.04 a check
- Professional$32.00
About $0.03 a check
- Enterprise$19.99
About $0.02 a check
Developers ask these questions before they add a pre-dial check
Do AI voice agent calls fall under the TCPA?
Yes. In a Declaratory Ruling adopted on 2 February 2024 and announced on 8 February 2024, the FCC ruled that calls made with AI-generated voices are artificial voices under the Telephone Consumer Protection Act. Those calls need the prior express consent of the person called, and prior express written consent when the call is telemarketing. The ruling took effect immediately.
What does Phone Scrub check before my AI voice agent dials?
One call returns three answers: whether the number is on a Do Not Call list, whether it belongs to a known TCPA litigator, serial complainer or attorney, and what kind of line it is (mobile, landline or VoIP). The response also carries a suggested action: APPROVE, REVIEW or BLOCK.
Does the check work with Vapi, Retell and Bland?
Yes. Phone Scrub is an ordinary HTTPS request that your own server makes before it asks Vapi, Retell, Bland or your own Twilio setup to place the call, so it needs nothing from the platform.
What does the API return for a Do Not Call or litigator number?
A Do Not Call number comes back with doNotCall set to true and the suggested action BLOCK. A known litigator comes back with litigator set to true, the line type LITIGATOR and BLOCK. A litigator number is never returned as APPROVE, even when it is not on a Do Not Call list.
How much does a pre-dial check cost?
A check costs 10 credits when the number is found and nothing when 1Lookup has no record of it. On the Starter plan that is about $0.05 a check, so a list of 1,000 numbers costs at most 10,000 credits, about $49.50. Every plan starts with a 7-day free trial.
Does Phone Scrub check numbers outside the US?
No. The scrub is built for US numbers, because the Do Not Call and TCPA litigator lists cover the United States only. A number from another country will not return a useful result.
Try the pre-dial check on your own numbers with a free trial
Create a key, send one number from your call list and read the answer before your agent dials it.
- Phone Scrub product pagePricing, CSV upload and the full list of questions.
- Free Do Not Call checkTry one number in the browser before you write code.
- Free TCPA litigator checkSee what a litigator result looks like.
- How litigator scrubbing worksWhat the list contains and where it fits in a calling workflow.