# Fraud Detection API - IP, Email, Phone and URL Risk Score (`nabeelbaghoor/fraud-detection-scoring-api`) Actor

Score any IP address, email address, phone number or URL for fraud. Proxy, VPN, Tor and bot detection with geolocation, email deliverability with disposable and catch-all checks, line type, carrier and SMS pumping risk, and phishing and malware scanning. Pay per result.

- **URL**: https://apify.com/nabeelbaghoor/fraud-detection-scoring-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Business, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$12.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Fraud Detection API - IP, Email, Phone and URL Risk Score

Four fraud checks behind one key. Give it an IP, an email address, a phone number or a URL, and get back a score from 0 to 100 plus the evidence behind it. One flat row per lookup.

### What this actor does

- **Scores four kinds of value on one scale.** IP addresses, email addresses, phone numbers and URLs all come back with a fraud score from 0 to 100 where higher is worse, so a threshold you tune on one service means the same thing on the others.
- **Separates the kinds of proxy.** Web proxy, VPN, active VPN, Tor, active Tor, data centre, residential, crawler and bot are distinct fields rather than one collapsed flag, because a corporate VPN, a residential proxy and a Tor exit node are three different findings that deserve three different responses.
- **Validates email properly, not just syntactically.** Deliverability, SMTP score, catch-all, disposable, generic, honeypot, spam trap score, frequent complainer, recent abuse, leaked in a breach, risky TLD, DNS and MX records, SPF and DMARC, domain age and trust, plus a suggested correction when an address looks like a typo of a real domain.
- **Tells you whether a phone number is actually in service.** Valid and active are different questions: a well-formed number in a real range can still be disconnected. You also get line type, carrier, VoIP and prepaid flags, do-not-call and TCPA list status, and an SMS pumping risk score, which is the one that matters if you send one-time codes.
- **Scans URLs for phishing, malware and parking.** Category, server, status code, final URL after redirects, technologies detected, domain age and rank, and separate phishing, malware, suspicious, spamming and adult flags.
- **Normalises the score the provider does not.** The URL service names its number a risk score while the other three call the same idea a fraud score. Both are written to one column here, so a single threshold filter works across a mixed set of runs.
- **Refuses inputs that cannot work, before they cost anything.** Every request is charged whether or not it returns a result, so a value that is not the kind this service looks up is refused locally and recorded as a refusal instead of being paid for.
- **Reads the body, not the status code.** This provider reports a refused key, a spent balance and a bad input with a normal HTTP 200. An actor that trusts the status code writes hundreds of empty rows and charges for them. This one decides on the body.
- **Never puts your key in a log.** The credential travels in the URL path with this provider, which makes every request URL a secret. Nothing here logs one.
- **Never charges for a miss.** Only rows carrying a resolved result are billed.

### Input

| Field | What it does |
| --- | --- |
| `mode` | Which service to run: IP, email, phone or URL. |
| `queries` | The values to score, one per line. |
| `strictness` | How aggressively the provider judges a value. |
| `allowPublicAccessPoints` | Stop penalising shared institutional networks. |
| `lighterPenalties` | Soften scoring to cut false positives. |
| `userAgent` | End user agent string, as an extra IP signal. |
| `userLanguage` | End user language, as an extra IP signal. |
| `timeoutSeconds` | How long the email service may spend per address. |
| `fastMode` | Skip the slowest email checks. |
| `phoneCountries` | Countries a national-format number might belong to. |
| `extraParams` | JSON query parameters passed through as written. |
| `minFraudScore` | Keep only rows scoring at or above this. |
| `maxFraudScore` | Keep only rows scoring at or below this. |
| `requireValid` | Keep only values the provider marked valid. |
| `deliverability` | Keep only these email deliverability levels. |
| `excludeDisposable` | Drop throwaway email domains. |
| `excludeCatchAll` | Drop catch-all domains. |
| `excludeRecentAbuse` | Drop values recently involved in abuse. |
| `excludeProxies` | Drop proxies, VPNs and Tor nodes. |
| `excludeBots` | Drop bots and crawlers. |
| `requireActivePhone` | Keep only numbers currently in service. |
| `excludeVoip` | Drop internet telephony numbers. |
| `lineTypes` | Keep only these phone line types. |
| `unsafeOnly` | Keep only URLs flagged unsafe. |
| `countries` | Keep only these countries. |
| `connectionTypes` | Keep only these IP connection types. |
| `requestsPerMinute` | Pace the run under your plan's rate limit. |
| `skipNotFound` | Leave misses and refusals out of the dataset. |
| `maxResults` | Hard cap on rows, and therefore on spend and run time. |
| `apiKey` | Your own API key. Stored as a secret. |

### Example output

```json
{
  "found": true,
  "mode": "ip-reputation",
  "query": "8.8.8.8",
  "requestId": "kJ9NgHNPnB",
  "fraudScore": 0,
  "isProxy": false,
  "isVpn": false,
  "isTor": false,
  "isActiveVpn": false,
  "isActiveTor": false,
  "isCrawler": false,
  "botStatus": false,
  "recentAbuse": false,
  "frequentAbuser": false,
  "highRiskAttacks": false,
  "abuseVelocity": "none",
  "securityScanner": false,
  "trustedNetwork": true,
  "sharedConnection": false,
  "dynamicConnection": false,
  "isMobile": false,
  "isp": "Google LLC",
  "organization": "Google Public DNS",
  "asn": 15169,
  "host": "dns.google",
  "connectionType": "Corporate",
  "countryIso2": "US",
  "region": "California",
  "city": "Mountain View",
  "zipCode": "94043",
  "timezone": "America/Los_Angeles",
  "latitude": 37.4056,
  "longitude": -122.0775,
  "error": null,
  "raw": { }
}
```

### Frequently asked questions

#### What does the fraud score mean?

It is a single number from 0 to 100 where higher is riskier, produced by the provider from every signal it holds about that value. Scores under about 75 are generally ordinary traffic, the 75 to 85 band is where suspicious activity starts, and above that is where most systems refuse or challenge. Those are starting points rather than rules: the right threshold depends on what you lose from a false positive against what you lose from a missed fraud, so run a sample of known-good and known-bad values through first and read the distribution before you set a cutoff.

#### What is the difference between the four services?

They take four different kinds of input and answer four different questions, so a run uses one at a time. The IP service answers whether a connection is what it claims to be: proxy, VPN, Tor, bot, and where it actually is. The email service answers whether an address will receive mail and whether it belongs to a real person. The phone service answers whether a number is valid, in service, and safe to send a code to. The URL service answers whether a link is dangerous. All four return a score on the same scale.

#### Why does the actor refuse some of my inputs before sending them?

Because this provider charges per request whether or not the request returns anything useful. A string with no at sign is not an email address, a string with fewer than seven digits is not a phone number, something that is neither four dotted numbers nor a colon separated hextet run is not an IP address, and a string with no dot in its host is not a URL. Sending those costs money and teaches you nothing. They are refused locally and written to the dataset as refusals with the reason, so a run that ignored part of its list does not look like a run whose provider found nothing.

#### Why did my run succeed but return nothing when my key was wrong?

It should not, and with this actor it does not. This provider reports a refused key, an exhausted balance and a malformed request with a normal HTTP 200 status and a body saying success false. An integration that checks the status code sees four hundred successful responses and writes four hundred empty rows. This actor decides on the body, tells the difference between a credential problem and a bad input from the message text, and ends the run cleanly with the reason as the run's status message when the credential is the problem.

#### What is strictness and should I raise it?

It controls how aggressively the provider judges a value. Zero is the balanced default, and each step up catches more genuine fraud while also flagging more legitimate traffic. Raise it one step at a time and compare what changed, rather than jumping to the maximum: at the top setting on the IP service you will catch nearly everything and also flag a good number of ordinary users on shared connections. If false positives are the bigger cost, leave strictness alone and turn on lighter penalties and allow public access points instead.

#### What is SMS pumping risk and why does it have its own field?

SMS pumping is a fraud where somebody triggers your one-time-code flow against premium-rate numbers they control and collects a share of the termination fees. It costs you real money without ever touching an account. The phone service returns a dedicated risk score for it, separate from the general fraud score, because the countermeasure is different: you are deciding whether to send a message at all rather than whether to trust a user.

#### Does the URL service follow redirects?

Yes, and the row records both ends: the address you submitted and the final address after redirects, along with the status code and the server. That matters because a shortened or cloaked link is safe-looking by design and the destination is the thing worth scoring.

#### Can I use a parameter this actor does not have a field for?

Yes. The extra parameters field takes a JSON object and appends it to the query string exactly as written. Each of the four services takes its own parameter set and the provider adds to them over time, so only the documented ones have named fields and anything else goes there. A parameter that does not apply to the service you are running simply has no effect.

#### Do I need my own API key?

Yes. This actor does not include data access. You use your own API key from IPQualityScore, which is the provider whose fraud scoring API this actor calls, taken from the settings page of your provider account and pasted into the `apiKey` field, where it is stored as an Apify secret. Your own plan, credit balance and terms apply.

#### What happens when a lookup returns nothing?

A negative answer is a result, not a miss: the provider telling you an address is undeliverable or a URL is malicious is exactly the question you asked, so that row is written and billed like any other. A miss is a value the provider would not answer for at all, and a refusal is an input that never left this actor. Both are written with `found: false` and never billed. Set `skipNotFound` to true to leave them out entirely.

#### How much does a run cost?

Pricing is pay per result: you are charged for each value scored into the dataset, and never for misses, for locally refused inputs, for rows dropped by the filters, or for duplicates. Apify platform usage is included in the per-result price. Your own API provider's credit balance is separate and billed by them.

### Keyword map

fraud detection API, fraud score API, IP reputation API, proxy detection API, VPN detection API, Tor exit node detection, residential proxy detection, data centre IP detection, bot detection API, IP geolocation API, email validation API, email verification API, disposable email detection, catch all detection, spam trap detection, email deliverability check, phone validation API, phone number lookup, line type detection, carrier lookup, VoIP detection, active phone number check, SMS pumping detection, do not call list check, TCPA compliance check, malicious URL scanner, phishing detection API, malware URL check, link safety API, domain reputation API, account takeover prevention, bot signup prevention, chargeback prevention, ad fraud detection

# Actor input Schema

## `mode` (type: `string`):

Which of the four services to call. Each one takes a different kind of input, so a run scores one kind of value at a time. Anything in the list that cannot be the kind this mode expects is refused before it is sent, since the provider charges per request either way.

## `queries` (type: `array`):

The IP addresses, email addresses, phone numbers or URLs to score, one per line, matching the service chosen above. The URL service accepts either a full address or a bare domain. Phone numbers should include the country code; spaces, plus signs, brackets and dashes are stripped before sending. Duplicates are looked up once.

## `strictness` (type: `integer`):

How aggressively the provider should judge a value, from zero for the default balance through to the strictest setting each service supports. Raising it catches more genuine fraud and also flags more legitimate traffic, so it is worth moving one step at a time and looking at what changed. Leave at zero for the provider's own default.

## `allowPublicAccessPoints` (type: `boolean`):

In the IP service, stop penalising shared connections such as universities, libraries, hotels and coffee shops. Worth turning on when your genuine users are on institutional networks, because otherwise a whole campus scores as one suspicious address.

## `lighterPenalties` (type: `boolean`):

In the IP service, soften the scoring so fewer legitimate users are caught. The setting to reach for when the false positive rate matters more than catching every last case.

## `userAgent` (type: `string`):

The browser user agent the end user came from, applied to every address in the IP service. The provider reads it as an extra signal, since a device that disagrees with the network it claims to be on is interesting in itself.

## `userLanguage` (type: `string`):

The browser language the end user came from, such as en-US, applied to every address in the IP service. Another cross-check: a language that does not match the geography is a signal.

## `timeoutSeconds` (type: `integer`):

In the email service, how long the provider may spend on a single address before answering with what it has. Raising it resolves more of the slow mail servers that would otherwise time out; lowering it finishes a long list faster. Leave empty for the provider's default of about seven seconds.

## `fastMode` (type: `boolean`):

In the email service, skip the slowest checks and answer sooner with slightly less certainty. Useful on very large lists where throughput matters more than resolving every borderline address.

## `phoneCountries` (type: `array`):

In the phone service, the two-letter country codes a number might belong to. This is a parsing hint rather than a filter: a number written without a country code is ambiguous, and telling the provider which countries are plausible is what makes national-format numbers resolve correctly.

## `extraParams` (type: `object`):

A JSON object of extra query parameters, sent exactly as written. Each service takes its own set and the provider adds to them over time, so rather than guess at a union, only the documented ones have named fields above and anything else goes here. A parameter that does not apply to the service you are running simply has no effect.

## `minFraudScore` (type: `integer`):

Only keep rows scoring at or above this on the zero to one hundred scale. Use it to turn a run into a review queue holding only what is actually suspicious. The URL service reports the same idea under its own name, and both are written to this column, so one threshold means one thing across all four services. Leave at zero to keep every score.

## `maxFraudScore` (type: `integer`):

Only keep rows scoring at or below this. The mirror of the minimum, and the one to use when you are building a clean list rather than a review queue. Leave at zero to keep every score.

## `requireValid` (type: `boolean`):

Drop rows the provider did not mark valid. Applies to the email and phone services, which are the two that answer that question.

## `deliverability` (type: `array`):

In the email service, only keep rows at these deliverability levels, as the provider names them: high, medium or low. This is the filter most email list cleaning actually wants. Leave empty to keep every level.

## `excludeDisposable` (type: `boolean`):

Leave out throwaway email domains, which are the usual signature of a signup that was never meant to be reachable.

## `excludeCatchAll` (type: `boolean`):

Leave out addresses on domains that accept mail for every possible mailbox, since those cannot be confirmed one way or the other.

## `excludeRecentAbuse` (type: `boolean`):

Leave out values the provider has seen involved in abuse recently. Works across all four services.

## `excludeProxies` (type: `boolean`):

In the IP service, drop addresses flagged as a proxy, a VPN or a Tor node.

## `excludeBots` (type: `boolean`):

In the IP service, drop addresses identified as automated traffic rather than a person.

## `requireActivePhone` (type: `boolean`):

In the phone service, drop numbers that are not currently in service. Being valid and being active are two different things: a well-formed number belonging to a real range can still be disconnected.

## `excludeVoip` (type: `boolean`):

In the phone service, leave out internet telephony numbers, which are cheap to obtain in bulk and are the usual shape of a throwaway signup.

## `lineTypes` (type: `array`):

In the phone service, only keep rows whose line type matches one of these, written as the provider names them, such as Wireless or Landline. Matching ignores capitalisation. Leave empty to keep every type.

## `unsafeOnly` (type: `boolean`):

In the URL service, keep only addresses the provider flagged as unsafe. This turns a scan of your whole link inventory into a list of just the problems.

## `countries` (type: `array`):

Only keep rows resolving to one of these two-letter country codes. Leave empty to keep every country.

## `connectionTypes` (type: `array`):

In the IP service, only keep rows whose connection type matches one of these, written as the provider names them, such as Residential, Corporate, Data Center or Mobile. Matching ignores capitalisation. Leave empty to keep every type.

## `requestsPerMinute` (type: `integer`):

Pace the run so it stays under whatever rate your plan allows. Lower this if the provider starts rate limiting; raise it to finish a long list sooner.

## `skipNotFound` (type: `boolean`):

Leave values the provider returned nothing for, and inputs refused before they were sent, out of the dataset. Off by default, because knowing which of your values were unusable is usually the point. Misses are never charged for either way.

## `maxResults` (type: `integer`):

Stop after this many rows. This is the cap on both spend and run time.

## `apiKey` (type: `string`):

Your own API key for the fraud scoring API, taken from the settings page of your provider account. Note that this provider carries the key in the request URL rather than in a header, so nothing in this actor ever logs a request URL. Stored as a secret.

## Actor input object example

```json
{
  "mode": "ip-reputation",
  "queries": [
    "8.8.8.8"
  ],
  "strictness": 0,
  "allowPublicAccessPoints": false,
  "lighterPenalties": false,
  "fastMode": false,
  "minFraudScore": 0,
  "maxFraudScore": 0,
  "requireValid": false,
  "deliverability": [],
  "excludeDisposable": false,
  "excludeCatchAll": false,
  "excludeRecentAbuse": false,
  "excludeProxies": false,
  "excludeBots": false,
  "requireActivePhone": false,
  "excludeVoip": false,
  "unsafeOnly": false,
  "requestsPerMinute": 300,
  "skipNotFound": false,
  "maxResults": 100
}
```

# Actor output Schema

## `results` (type: `string`):

One row per value scored, carrying the fraud score and the proxy, deliverability, line type or threat attributes for the service that was run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "8.8.8.8"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/fraud-detection-scoring-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "queries": ["8.8.8.8"] }

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/fraud-detection-scoring-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "8.8.8.8"
  ]
}' |
apify call nabeelbaghoor/fraud-detection-scoring-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/fraud-detection-scoring-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/HbdwEC2BDrSAHMEEx/builds/u7GLkMZPkLNWDNXbO/openapi.json
