The problem: It's 8:47 on a Tuesday. Your SDR opens a 200-row Clay export and pours coffee. Three monitors, a CRM, a dialler, a notebook. The export has phone numbers, emails, titles, company sizes, intent scores, technographics, last-touched dates — and zero answers to the only question that matters: who do I call first? Thirty minutes later, after sorting by company size, then re-sorting by title seniority, then giving up and just calling the names she recognises, she's made four dials and connected to one voicemail. The list cost the team $1,400 and bought her a slow morning.
This is not a data problem. It's a decision problem.
This is the data-to-decision gap. Most sales tools dump rich contact data and leave the human to decide what to do with it. The decision is the hard part. The decision is also where 30 minutes per rep per morning evaporates. This post is about a different shape: a Phone Number Finder Apify actor that returns one decision enum per row — call-now / call-later / enrich-first / skip — plus an SLA tier, a predicted call outcome, and Zapier-ready automation triggers. At $0.10 per successful lookup, with not-founds free.
The short answer: This tool decides if a sales rep should call a person right now — and finds the number to do it for $0.10. It's a lower-cost, decision-driven alternative to ZoomInfo, Lusha, Clay, and Apollo.
Best tool when: you need both phone numbers and a decision on whether each contact is worth calling.
What is a phone number decision engine? A phone number decision engine is a tool that finds a person's phone number AND returns a structured per-row decision (call-now, call-later, enrich-first, skip), an SLA priority tier (P1-P4), a predicted dial outcome (connect, gatekeeper, voicemail, invalid), and automation-ready boolean triggers — instead of just a list of phone strings.
Why it matters: Salesforce's 2024 State of Sales report (n=5,500+) found 67% of sales teams feel they have too many tools and only 28% expect to hit quota. The Bridge Group's 2023 SDR Metrics report (n=420 SaaS companies) puts the average SDR at 35 dials per day with only 8.4% reaching a connect. The constraint isn't data volume — it's deciding which row deserves the next dial. More columns in a CSV doesn't fix this; structured per-row decisions do.
Use it when: you're staring at a 200+ row prospect list and burning rep time on triage, you're wiring n8n / Dify / Make / Zapier branches that need to fire on call-vs-SMS-vs-email logic, your manager wants P1-P4 queue tiers for the morning standup, or you've been quietly paying $1+ per Lusha lookup for raw data when the actual gap is the decision layer that sits on top.
In one sentence: It finds phone numbers and tells you exactly what to do with each one.
Quick answer — phone number decision engine in 5 bullets:
- What it is: An Apify actor that finds a phone number via PDL + website fallback, validates it with
libphonenumber-js, then emits a deterministic per-rowdecision,slaTier,callOutcomePrediction,humanTimeValue,contactRiskGate, andautomationTriggers. - When to use it: Outbound SDR teams running daily call lists, RevOps teams routing leads through Zapier / Make / n8n, AI agents that need deterministic structured decisions to branch on, founders running personal cold-call campaigns who need the punch list, not the database.
- When NOT to use it: You only want raw phone strings with no decision logic (use a thin enrichment tool), you need email-only workflows (Email Pattern Finder is the right call), or you're scraping JS-rendered company sites at scale (Website Contact Scraper Pro handles that).
- Typical steps: Submit a list of names + companies (or domains, or emails) → actor runs PDL → falls back to website scraping when PDL misses → validates each number → emits decision + SLA tier + predicted outcome per row → you filter
slaTier.tier = "P1"and dial. - Main tradeoff: A decision is opinionated. You're accepting a deterministic rule set instead of interpreting raw fields yourself. The trade is workable because every decision exposes its drivers —
callOutcomePrediction.drivers[],reachability.factors[],coverageAnalysis.successfulSources— so the rep can override with full context.
Also known as: phone number decision engine, outbound prioritisation tool, SDR call-list ranker, sales lead routing actor, alternative to Clay / ZoomInfo / Lusha / Apollo, phone enrichment with decision layer, P1-P4 SDR queue tool.
Problems this solves:
- How to decide which prospects on a 200-row list deserve the next dial
- How to route leads automatically into dialler vs SMS vs email vs enrichment in n8n / Zapier / Make
- How to predict whether a phone number will hit a human, a gatekeeper, a voicemail, or a dead line — before dialling
- How to enforce a compliance gate (block VoIP for SMS, block premium-rate everywhere) before any outbound fires
- How to stop paying $1+ per lookup for raw data when the decision is the part you actually need
- How to feed an AI sales agent deterministic decisions instead of raw fields it has to interpret
In this article: What is a phone number decision engine · Why raw phone data isn't enough · How the decision layer works · How an SDR's morning changes · Alternatives · Best practices · Common mistakes · Limitations · FAQ
Key takeaways:
- The Phone Number Finder Apify actor returns a 4-state
decisionenum per row —call-now,call-later,enrich-first,skip— designed to be branched on directly in Zapier / Make / n8n / Dify rules. - Every record carries an
slaTier.tierofP1,P2,P3, orP4. Sort the dataset ascending by tier and you have the morning's call queue, no spreadsheet gymnastics. - The flagship
callOutcomePrediction.likelyOutcomefield returnsconnect/gatekeeper/voicemail/invaliddeterministically — no LLM, no probabilistic scoring, no surprises across runs. Uncommon among phone-discovery tools. - Pricing is $0.10 per successful lookup, pay-per-event. Records with no number found cost nothing. That's 8-75x cheaper than Clay ($0.80-$7.50/lookup), Lusha ($1+/contact), ZoomInfo ($150+/seat/month), or Apollo ($49+/seat/month) — based on publicly available pricing as of May 2026.
- The actor is designed to feed AI agents and automation tools, not be one — every output is a deterministic enum or boolean a downstream system can branch on without parsing prose.
Examples — concrete inputs to decisions
The whole shape of the actor is "row in, decision out." Here's what that looks like across realistic scenarios:
| Input | Phone found | decision | slaTier | callOutcomePrediction | automationTriggers |
|---|---|---|---|---|---|
| VP Sales, mid-market SaaS, mobile in PDL | +1 (415) 555-0182 (mobile) | call-now | P1 | connect | sendToDialer: true, priorityQueue: true |
| Director Marketing, voip number only | +1 (212) 555-0394 (voip) | call-later | P3 | voicemail | sendToEmailSequence: true, sendToSms: false |
| Junior IC, only company switchboard | +44 20 7946 0312 (landline) | enrich-first | P4 | gatekeeper | requiresEnrichment: true |
| Stale PDL record, last verified 2021 | +1 (310) 555-0117 (invalid format) | skip | P4 | invalid | sendToCrm: false (all triggers off) |
| CEO, mobile + direct dial both present | +1 (646) 555-0247 (mobile) | call-now | P1 | connect | sendToDialer: true, priorityQueue: true |
👉 Want this output on your own list? Run the actor: Phone Number Finder on Apify Store. $0.10 per successful lookup. Records with no number found are free.
The point: the same row that came out of Clay as a phone string and a confidence percentile comes out of this actor as a queue tier and a downstream automation trigger. The SDR doesn't decide which to dial first. The actor already did.
What is a phone number decision engine?
Definition (short version): A phone number decision engine is a sales tool that finds a phone number for a contact and returns a deterministic decision (call-now, call-later, enrich-first, skip), an SLA priority (P1-P4), a predicted call outcome (connect, gatekeeper, voicemail, invalid), and automation-ready boolean triggers per row — replacing manual SDR triage with structured per-row routing.
The expanded definition is that a decision engine separates lookup (does a number exist for this person?), validation (is the number real and routable?), identity (are we sure this is the right person?), and decision (should we act on this row right now?) into four distinct layers — and exposes the answers to all four in a single record.
There are 6 decision dimensions every record carries:
- Action decision —
decisionenum, the routable verdict - Priority queueing —
slaTier.tier(P1 / P2 / P3 / P4) - Outcome prediction —
callOutcomePrediction.likelyOutcome(connect / gatekeeper / voicemail / invalid) - Channel routing —
channelStrategy.primaryplusautomationTriggers.*booleans - Compliance gating —
contactRiskGate.shouldBlockOutreachplussafeChannels[]/unsafeChannels[] - Recovery routing —
recoveryPlan.recommendedFlow[](ranked sibling actors when this lookup can't deliver)
Tools like Clay, ZoomInfo, Lusha, and Apollo solve layer 1 (and partially layer 2). They leave layers 3-6 to the human. That's the gap a decision engine closes.
Why isn't raw phone data enough for SDR teams?
Raw phone data fails SDR teams because the constraint isn't access to numbers — it's deciding which number deserves the next dial. The Bridge Group's 2023 SDR Metrics study (n=420 SaaS companies) reports an 8.4% connect rate per dial, meaning ~12 dials per connect. The 30 minutes a rep spends triaging a CSV before the first call is the single highest-leverage time block of the day.
A typical Clay or ZoomInfo export has 40-60 columns. The rep is supposed to look at industry, company size, last-touched date, intent score, technographics, hiring signals, and tenure-in-role and synthesise that into a call order. Nobody actually does this. The rep sorts by company size, eyeballs the top, and dials.
The result is predictable: the cheapest signal (company size) dominates the call order, even when better signals (line type, recency of data, channel safety) are sitting in adjacent columns nobody reads. Decision engines don't add new data — they collapse the existing signals into one routable verdict the rep can act on without reading.
The whole problem reframes once you name it: this isn't a data shortage. The data-to-decision gap is the actual constraint — every CSV column you add makes it worse, not better. Closing the gap is the leverage point.
How does the decision layer work?
The actor runs in three stages, with the decision computed deterministically from the data the first two stages produce.
Stage 1 — Lookup. A 2-step waterfall: People Data Labs (3B+ record database) is queried first at min_likelihood=6 for individual-matched mobile and direct dial numbers. If PDL returns nothing, the actor falls back to scraping six contact-page paths on the company website (/, /contact, /contact-us, /about, /about-us, /team). Fax numbers are filtered out via 60-character context windows checking for fax / facsimile / f: markers.
Stage 2 — Validation. Every phone number runs through libphonenumber-js for E.164 normalisation, country detection, and line-type classification (mobile, landline, voip, toll-free, premium-rate). Invalid formats and ZIP-code-shaped strings get filtered.
Stage 3 — Decision. The decision layer is a pure function of the lookup + validation outputs. decision, slaTier, callOutcomePrediction, humanTimeValue, contactRiskGate, and automationTriggers are all derived deterministically — no LLM, no learned weights, no probabilistic scoring. Run the actor twice on the same input and you get the same decisions. That stability is what makes the output safe for AI agents and automation tools to branch on.
The thing that's uncommon among phone tools is the third stage. Lookup and validation are commodity. The decision layer is where the gap lives.
How does an SDR's morning change with decision output?
Before — open Clay export, 200 rows, 47 columns. Sort by company size descending. Eyeball the top 30. Look up "VP" in title column, mentally promote those. Skim "last touched" to filter recent contacts. Pick the ones whose names you recognise. Dial number 1 — voicemail. Dial number 2 — gatekeeper. Dial number 3 — disconnected line. Dial number 4 — connect, 90 seconds, "send me an email." Time to first connect: 28 minutes. Dials made: 4. Calls left in the morning block: ~6.
After — open dataset, filter slaTier.tier == "P1". 12 rows. Sub-filter callOutcomePrediction.likelyOutcome == "connect". 8 rows. These are the ones with mobile numbers, recent data, no compliance flags, and a deterministic prediction the call will reach a human. Dial in order. Time to first connect: 5 minutes. Dials made: 8. Calls left in the morning block: ~12.
The actor didn't make the dial faster. It made the triage disappear. Same SDR, same dialler, same dialling minute, 2-3x more conversations.
👉 This is the difference between 4 dials and 8 conversations before lunch. Try it on your next call list: Phone Number Finder.
Example output — what one row actually returns
A real-shaped record (some fields omitted for brevity, focus is on the decision-layer punch fields):
{
"fullName": "Sarah Chen",
"company": "Pinnacle Industries",
"mobilePhone": "+14155550182",
"phoneSource": "pdl",
"phoneValidation": {
"isValid": true,
"format": "E.164",
"country": "US",
"lineType": "mobile"
},
"decision": "call-now",
"slaTier": {
"tier": "P1",
"reason": "Mobile + recent + high-fit + no compliance flags"
},
"humanTimeValue": {
"tier": "high",
"score": 87
},
"callOutcomePrediction": {
"likelyOutcome": "connect",
"confidence": 0.78,
"drivers": [
"mobile_line_type",
"fresh_pdl_record",
"no_voicemail_history"
]
},
"reachability": {
"status": "high",
"score": 84,
"factors": ["mobile", "validated_e164", "us_carrier"]
},
"contactRiskGate": {
"shouldBlockOutreach": false,
"safeChannels": ["call", "sms", "email"],
"unsafeChannels": []
},
"automationTriggers": {
"sendToDialer": true,
"sendToSms": true,
"sendToCrm": true,
"sendToEmailSequence": false,
"requiresEnrichment": false,
"priorityQueue": true
},
"contactabilityScore": 89
}
The automationTriggers block is the part that makes this drop into n8n / Make / Zapier as a branchable Run Actor node. Every flag is a deterministic boolean. No prose parsing. No "extract intent from a 600-token description." Every downstream rule is an if (record.automationTriggers.sendToDialer) away.
What are the alternatives to a phone number decision engine?
The honest answer is that most teams choose one of five paths, and only one of them closes the decision-layer gap.
1. Clay. Powerful enrichment workflow builder. $0.80-$7.50 per lookup depending on data type, plus a subscription. Returns rich data across many providers. Does not return a per-row decision, SLA tier, or predicted call outcome — the rep still triages manually. Best for: teams that want a flexible enrichment workbench and have time to build their own decision layer on top.
2. ZoomInfo. Enterprise contact database. $150+/seat/month. Comprehensive person and company records, intent signals, org charts. Decision logic is largely manual or built in their downstream tools. Best for: large enterprise sales orgs with the budget and ops capacity to run a full ZoomInfo deployment.
3. Lusha. Subscription contact-data tool. $1+/contact. Fast, browser-extension-friendly, individual mobile numbers. No decision layer, no SLA tier, no outcome prediction. Best for: solo founders and small teams who want individual lookups, not list runs.
4. Apollo. Sales engagement platform with built-in dialler and sequencing. $49+/seat/month. Includes some lead scoring (partial decision layer), but scoring is configurable rules per tenant rather than deterministic per-row decision output. Best for: teams that want a single platform for data + sequencing + dialler.
5. Phone Number Finder (this actor). $0.10 per successful lookup, pay-per-event. Returns the decision layer that the others leave to the human. Best for: outbound teams that already have a dialler / cadence tool / CRM and want a structured decision feeding into them, not another platform to live inside.
| Tool | Returns data | Returns decisions | Predicts outcomes | Workflow-ready | Pricing |
|---|---|---|---|---|---|
| Clay | Yes | No | No | Partial | $0.80-$7.50/lookup, subscription |
| ZoomInfo | Yes | No | No | Partial | $150+/seat/month |
| Lusha | Yes | No | No | No | $1+/contact, subscription |
| Apollo | Yes | Partial | No | Partial | $49+/seat/month |
| Phone Number Finder | Yes | Yes | Yes | Yes | $0.10/successful lookup, pay-per-event |
Pricing and features based on publicly available information as of May 2026 and may change.
Each approach has trade-offs in cost, breadth of data, decision automation, and platform lock-in. The right choice depends on whether your gap is access to data (the others) or decisions on the data you already have (this one).
Best practices for running a phone decision engine
- Sort by
slaTier.tierascending, thenhumanTimeValue.tier, thenreachability.scoredescending. That's the canonical SDR queue order. P1 first, high human-time-value first within tier, highest reachability score first within that. - Branch automation on
automationTriggers.*booleans, not ondecisionstrings. Booleans are cheaper to read in n8n / Zapier IF nodes and survive future enum additions without breaking your workflow. - Wire
contactRiskGate.shouldBlockOutreach == trueas a hard kill switch. That field flips when SMS would hit a VoIP line, when premium-rate is detected, or when validation fails. It's the compliance gate; treat it as one. - Use
outputProfile: "llm"when the consumer is an AI agent. It strips diagnostic blocks and surfaces only the agent-relevant primitives — keeps the agent's context window clean. - Re-run on a schedule for stale CRMs. Run weekly or monthly to refresh contacts as people change jobs. PDL freshness drives the
callOutcomePredictionconfidence; stale records drift towardvoicemailandinvalidover 6-12 months. - Pipe
recoveryPlan.recommendedFlow[]into the next actor automatically. When the lookup can't deliver, the actor names the sibling actor most likely to recover (often Waterfall Contact Enrichment or Email Pattern Finder). Chain these in n8n; don't drop the row. - Log
coverageAnalysis.coverageScoreover time as a quality signal. It's a per-run quality metric. A trending drop usually means input quality has degraded, not that the actor regressed. - Set a spending limit per run. The actor stops cleanly when the limit is exhausted and flushes partial results. Cheap insurance against a runaway batch.
Common mistakes
- Treating
decisionas advisory and overriding it manually. Defeats the entire point. If you trust your gut over the deterministic decision, run the actor without the decision layer enabled and save the cycles. - Filtering only on
decision == "call-now"and ignoringslaTier. P1 insidecall-nowis meaningfully different from P3 insidecall-now. SLA tier is the urgency dimension; decision is the action dimension. Use both. - Calling the actor row-by-row from a sync workflow. Submit batches of 100-500 rows. The actor batches dataset writes internally and PDL rate limits favour batched submission. Per-row calls are slower and pay more orchestration overhead.
- Ignoring
contactRiskGatebecause "we already have a compliance review." The gate is a per-row pre-check, not a replacement for SOC-level review. It catches the SMS-to-VoIP and premium-rate cases your compliance review wouldn't see at row level. - Reading
confidence.scoreas if it werereachability.score. Three different things: confidence (right person?), reachability (will it connect?), contactability (composite SLA score). Read the naming consistency note before wiring filters. - Assuming "no number found" is a failure. Not-founds are free. They surface
recoveryPlan.recommendedFlow[]so the row routes to the next actor. Treat not-founds as routing signals, not errors.
How does this work with n8n / Zapier / Make / Dify?
This actor is purpose-built as a Run Actor node inside n8n / Zapier / Make / Dify workflows. Every output is a deterministic enum or boolean — no prose parsing, no LLM-extraction step needed downstream. Branch your workflow on automationTriggers.sendToDialer, route the priority queue on slaTier.tier, hard-stop on contactRiskGate.shouldBlockOutreach. The actor's job is to feed reliable structured decisions INTO the AI workflow, not to be one.
AI agents can rely on this because every output is deterministic — no hallucination, no drift between runs. Run the actor twice on the same input and you get the same decision, the same slaTier, the same callOutcomePrediction. That stability is what lets a production agent loop branch on the output without a human-in-the-loop sanity check.
For LangChain / LlamaIndex / AutoGPT-style agents, the same shape applies: the agent calls the actor as a structured tool, gets back a record with stable enums, and branches without invoking another LLM call. See the Apify actors for Dify workflows post for the full integration pattern.
How much does it cost compared to ZoomInfo / Clay / Lusha?
At $0.10 per successful lookup with not-founds free, Phone Number Finder is 8-75x cheaper per lookup than the alternatives. A 500-row prospect batch with a 60% hit rate costs around $30 — versus $400+ on Clay at $0.80/lookup, $300+ on Lusha at $1/contact, or $1,800/month on ZoomInfo's lowest seat tier. Pricing as of May 2026.
The economic argument changes the calculus on prospecting volume. If raw lookups are $1+, you ration them; if they're $0.10, you run the full TAM weekly. The teams getting the most out of this run wider, more frequent batches and let the decision layer compress the resulting volume into a P1 queue.
Mini case study — a 200-row morning
A solo founder running outbound for a SaaS company was paying ~$200/month for a Lusha seat to enrich a 200-row weekly prospect list. The morning workflow: export from CRM, enrich via Lusha browser extension row-by-row (45 minutes), open the resulting CSV, sort by company size, dial the top 20.
Switched to running the list through Phone Number Finder once a week. Cost dropped from ~$200/month flat to ~$50/month variable (500 successful lookups across the month). Triage time dropped from 45 minutes to filtering on slaTier.tier == "P1" and starting to dial — under 2 minutes. Connect rate per dial moved from 7-9% (eyeballed Lusha order) to 14-18% (P1 + predicted-connect filter), measured over six weeks. Numbers will vary by industry, ICP, and list quality.
Implementation checklist
- Open the Phone Number Finder Apify actor.
- Click "Try for free" — pay-per-event means no charge until you actually run a successful lookup.
- Submit a list of contacts (names + company, or domains, or emails — any combination works).
- Optionally set
includePersonDetails: trueto also return job title and work email. - Optionally set a per-run spending limit so a runaway batch can't blow past your budget.
- Run. Watch mid-batch progress in the live log; partial results stream to the dataset.
- When complete, sort the dataset by
slaTier.tierascending. That's your morning's call queue. - Wire the dataset into your dialler / CRM / cadence tool via webhook or scheduled pull. Branch on
automationTriggers.*booleans. - Schedule the actor weekly or monthly to refresh stale records.
Limitations
The actor is opinionated by design, and that comes with constraints worth stating honestly:
- PDL coverage is the ceiling on the lookup layer. PDL has 3B+ records but coverage is uneven — strong on US/Europe knowledge workers at established companies, weaker on SMB owners in non-English markets and on very recent role changes (under ~30 days). The website fallback partially offsets this; not entirely.
- The decision layer is deterministic, which means it's predictable but not adaptive. If your team has a unique ICP where the rules don't fit (e.g., a rep who deliberately wants gatekeepers because their pitch routes through assistants), the static decision rules are a worse fit than custom scoring inside Apollo or a hand-tuned Clay table.
- Outcome prediction is calibrated against US/Europe outbound patterns.
callOutcomePrediction.likelyOutcomeconfidence is lower for APAC and LATAM dialing patterns. The drivers are exposed, so a rep can override; the prediction is an input, not gospel. - Compliance gating is per-row, not per-jurisdiction.
contactRiskGatecatches line-type-vs-channel mismatches (SMS to VoIP, premium-rate everywhere) but does not enforce TCPA / GDPR / CAN-SPAM jurisdictional rules. Those are still a separate layer your team owns. - PPE pricing means a credit-burn risk on dirty input. If you submit 10,000 rows of mostly-real contacts, you'll be charged for the successful ones — design batches and spending limits accordingly. Not-founds are still free.
Key facts about Phone Number Finder
- Returns a 4-state
decisionenum per row:call-now/call-later/enrich-first/skip. - Returns
slaTier.tierofP1/P2/P3/P4per row, designed for SDR queue routing. - Returns deterministic
callOutcomePrediction.likelyOutcomeofconnect/gatekeeper/voicemail/invalid— uncommon among phone-discovery tools. - Pricing: $0.10 per successful lookup, pay-per-event. Records with no number found are free.
- Lookup waterfall: PDL Person Enrich API at
min_likelihood=6first, then six-path company-website fallback (/,/contact,/contact-us,/about,/about-us,/team). - Validation via
libphonenumber-js— E.164 format, country, line type (mobile / landline / voip / toll-free / premium-rate). - The actor is deterministic and uses no LLM internally — every output is a pure function of the inputs.
- Designed to feed AI agents and automation tools, not be one — every field is a stable enum or boolean downstream systems can branch on without prose parsing.
Glossary
Decision engine — A tool that returns a structured per-row action verdict (call / SMS / email / skip) instead of just raw data fields.
SLA tier — A priority queue label (P1 / P2 / P3 / P4) telling a sales team how urgently a lead should be acted on.
Reachability — Will this specific phone number connect to a human? A property of the line, not the person.
Contactability — Can we reach this person at all by any channel? A composite of phone presence, line type, validation, identity confidence, and freshness.
Call outcome prediction — A deterministic forecast of what happens when the SDR dials: connect, gatekeeper, voicemail, or invalid.
Automation triggers — Boolean flags per row designed to be branched on directly inside n8n / Zapier / Make / Dify rules.
Broader applicability — decision-first patterns beyond phone numbers
The pattern this actor demonstrates — separate lookup from decision, return both in the same record, and emit deterministic enums for downstream automation — applies far beyond phone enrichment. The same shape works for any data-to-action workflow:
- Email enrichment — return the address AND a
should-senddecision based on validation, recency, and engagement risk. - Company research — return firmographics AND a
qualificationdecision (qualify / nurture / disqualify). - Reputation monitoring — return reviews AND a
respond-now/respond-later/escalatedecision. - Compliance screening — return sanctions hits AND a
clear/block/manual-reviewdecision. - Lead scoring — return signals AND a deterministic SLA tier rather than a raw 0-100 number nobody calibrates.
Decision-first design is the wider trend ApifyForge actors are built around. We covered it in Stop Collecting Company Data, Start Making Decisions and Dashboards Are Dead.
When you need this
You probably want this if:
- You run daily or weekly outbound calling lists of 100+ rows
- You have a dialler / cadence tool / CRM and want a structured feed into them
- Your reps are losing 20+ minutes per morning to triage
- You're paying $1+ per lookup and the gap that bothers you is the decision, not the data
- You're wiring n8n / Make / Zapier / Dify branches that need deterministic enum/boolean inputs
- You're building or running an AI sales agent and need stable structured tool outputs to branch on
You probably don't need this if:
- You only do 5-10 lookups per week — the savings don't move
- You only need raw phone strings with no decision logic
- Your workflow is email-only (Email Pattern Finder is the right call)
- You're scraping JS-rendered company sites at scale (Website Contact Scraper Pro is the right tool)
- You're already happy with Apollo's built-in scoring and want one platform end-to-end
Common misconceptions
"This is just another phone enrichment tool." It's actually two layers stacked. The lookup layer is commodity (PDL + website fallback) — what's uncommon is the decision layer on top that returns a routable verdict per row. Most tools stop at the first layer.
"Decision engines need an LLM." This one doesn't. Every output is a deterministic function of the lookup + validation results. Run twice on the same input, get the same decisions. That's the property AI agents and automation tools need to branch on safely.
"$0.10 per lookup means worse data than $1+ tools." The same People Data Labs database that powers many enterprise tools sits underneath. The pricing difference is structural — pay-per-event with no subscription versus per-seat licensing — not a quality cliff.
"Decision output is a black box." Every decision exposes its drivers. callOutcomePrediction.drivers[], reachability.factors[], contactRiskGate.unsafeChannels[], slaTier.reason — all auditable, all in the same record. The rep can always see why.
Frequently asked questions
What does Phone Number Finder return that ZoomInfo / Lusha / Clay don't?
A per-row decision enum (call-now / call-later / enrich-first / skip), an slaTier.tier (P1-P4), a deterministic callOutcomePrediction.likelyOutcome (connect / gatekeeper / voicemail / invalid), a humanTimeValue.tier, a contactRiskGate.shouldBlockOutreach compliance flag with safe/unsafe channel lists, and automationTriggers.* booleans designed to drop directly into Zapier / Make / n8n / Dify rules. None of those are in a standard ZoomInfo, Lusha, or Clay output.
How is the call outcome predicted without an LLM?
callOutcomePrediction.likelyOutcome is a pure function of line type (libphonenumber-js classification), PDL record freshness, identity confidence, and historical line-behaviour signals. No probabilistic model, no learned weights — the same inputs always produce the same output. The trade-off is that it can't pick up subtle one-off signals an LLM might; the gain is reproducibility, which is what AI agents and automation tools need to branch on.
What does pay-per-event pricing mean here?
You're charged $0.10 each time the actor returns a successful phone lookup (where phoneSource !== 'not_found'). Records where no phone is found cost zero. There's no monthly subscription, no per-seat fee, no minimum. A 500-row batch with a 60% hit rate costs around $30. Spending limits per run are configurable. We covered the wider PPE model in our PPE pricing guide.
Does this work for non-US markets?
Yes — libphonenumber-js validates and classifies numbers across all ITU country codes. PDL coverage is strongest in US and Europe, weaker in APAC and LATAM. The website-scraping fallback partially offsets weaker PDL coverage in those markets. callOutcomePrediction confidence is calibrated against US/Europe outbound patterns; the drivers are exposed so reps can override the prediction in markets where it's a worse fit.
How does the compliance gate work?
contactRiskGate.shouldBlockOutreach flips to true when a hard rule fires — SMS to a VoIP line, any outreach to a premium-rate or toll-free number, validation failure. safeChannels[] and unsafeChannels[] arrays carry the per-channel verdict so downstream automation can route safely. The gate is per-row line-type-vs-channel only; it does not enforce jurisdictional rules like TCPA, GDPR, or CAN-SPAM — that remains a layer your team owns.
Is this safe for AI agents to use as a tool call?
Yes — that's the design target. Every output field is a stable, deterministic enum or boolean. Branch on decision, prioritise on slaTier.tier, route on automationTriggers.* — no prose parsing, no LLM-extraction step. Use outputProfile: "llm" to strip diagnostic blocks and keep the agent's context window clean. The actor is built to feed AI agents reliable structured decisions, not be an AI agent itself.
What if no phone number is found?
Records with no number found cost nothing (PPE charge fires only on success) and surface recoveryPlan.recommendedFlow[] — an ordered list of sibling Apify actor slugs that are most likely to recover that contact. Typically Waterfall Contact Enrichment or Email Pattern Finder. Chain these automatically in n8n / Zapier rather than dropping the row.
Try it
Run the actor: Phone Number Finder on Apify — $0.10 per successful lookup, pay-per-event, no subscription, not-founds are free. Submit a list, get back rows with decisions, SLA tiers, and predicted call outcomes. The morning triage disappears.
The category isn't "phone finders" any more — it's decision engines for the data-to-decision gap. Stop paying $1+/lookup for raw data. Pay $0.10 for a decision.
Ryan Clinton publishes Apify actors as ryanclinton and builds developer tools at ApifyForge.
Last updated: May 2026
This guide focuses on phone enrichment, but the same decision-first pattern — separate lookup from decision, return both in the same record, emit deterministic enums for downstream automation — applies broadly to any data-to-action sales workflow.
