# Website Legit Checker: Online Store Risk Signals & Trust Score (`reliable_tools/website-legit-checker`) Actor

Is this website legit? Collect public risk signals for online stores: domain age, TLS, email records, legal pages, company register, blocklists, payment and pricing signals. Trust score 0-100 with reasons, for your own review; not a statement about any merchant.

- **URL**: https://apify.com/reliable_tools/website-legit-checker.md
- **Developed by:** [Reliable Tools](https://apify.com/reliable_tools) (community)
- **Categories:** E-commerce, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $17.00 / 1,000 website checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Website Legit Checker: Is This Website Legit? Online Store Risk Signals and Trust Score

**Website Legit Checker** helps you check whether an online store or website looks legit by collecting public risk
signals for each domain, up to 200 domains per run. For every domain you get a **trust score from 0 to 100**, a risk
signal level and the reasons behind it: domain age and registrar, TLS certificate, email records, third-party
phishing and scam blocklists, legal pages (imprint, privacy, terms, returns), the physical address, the company behind
the site matched against an official register, payment methods, social profiles and unusually low pricing.

The result is an automated set of signals to help you decide where to look closer. It is not a statement of fact about
any merchant, and every row says so in its `disclaimer` field.

### What it does

For each domain or URL you enter, the Actor:

1. Reads the **domain registration** from the official registry over RDAP: registration date, age in days, expiry,
   registrar and status codes (such as "client hold" when a registry has suspended a domain). Only RDAP is used, never
   bulk WHOIS. At most 100 registry lookups are made per run, paced per registry, and .de domains are not looked up at
   all because DENIC allows its data only for technical or administrative purposes.
2. Checks **DNS**: MX records (can the domain receive email?), SPF and DMARC.
3. Checks the **TLS certificate**: valid or not, issuer, valid from and to, days left. After robots.txt allows it, it
   also checks whether plain http redirects to https.
4. Looks the domain up in **third-party public blocklists** of phishing, scam and malware domains. No connection at all
   is made to a listed website (no TLS check, no page request); only DNS and the list data are used.
5. Reads the **homepage and up to 6 legal pages** by default (you can raise this to 10) linked from it (imprint,
   contact, returns or refund policy, terms, privacy, about, shipping). robots.txt is read first, and the website gets
   one request at a time.
6. Detects the **shop platform** (Shopify, WooCommerce, Magento, BigCommerce, Wix, Squarespace, Shopware, PrestaShop,
   Shopline, Shoplazza and more), visible **payment methods** and **social media links**.
7. Finds the **contact details**: emails (own domain or free mail), phone numbers and a physical address, with the exact
   line from the site.
8. Finds the **company name** behind the site and looks it up in the **GLEIF LEI register** (and UK Companies House
   if you add a free key).
9. Samples up to 30 products from the public catalog of Shopify and WooCommerce stores to measure **discounts**, and
   notes **unusually low pricing** such as branded goods at 80 to 90 percent off.
10. Spots **parked, for-sale and placeholder pages**, and handles dead domains and redirects.
11. Adds an **AI assessment with probabilities**: are the legal pages genuine and specific to this business, how
    complete are they, is a physical address stated, are prices unusually low for the goods.
12. Combines everything into a **trust score from 0 to 100** with a list of reasons, each with its points, so you can
    see exactly why a site scored as it did.

### Who uses it

- **Payment providers and marketplaces** onboarding merchants (KYB and merchant risk checks).
- **AI shopping and payment agents** that need a legitimacy check before buying from an unknown store.
- **Affiliate networks, ad networks and lead platforms** screening the sites they send traffic to.
- **Fraud and trust and safety teams** triaging reported domains for manual review.
- **Chargeback and dispute teams** gathering signals before a person reviews a merchant.

The results are meant for your own internal review. Please do not publish the score or risk level as a statement
about a named merchant.

### Output

One row per domain. Main fields:

| Field | What it means |
|---|---|
| `trustScore` | 0 to 100. Higher means more signals of a real, accountable business |
| `verdict` | Risk signal level: `few_risk_signals` (75+), `some_risk_signals` (55 to 74), `several_risk_signals` (35 to 54), `many_risk_signals` (below 35), or `not_enough_data` when the website could not be read and nothing stands out at domain level |
| `disclaimer` | In every row: automated risk signals only, not a statement of fact about the merchant; verify before acting |
| `status` | `checked`, `parked`, `unreachable`, `not_registered`, `invalid_input` or `error` |
| `summary` | One sentence with the main risk signals and positive signals |
| `reasons` | Every signal with its points, strongest first |
| `checkCoverage` | `full` when legal pages were read, `homepage_only` when only the homepage could be read (for example a site built entirely with JavaScript), `domain_only` when only domain, TLS, email and blocklist checks were possible |
| `domainAgeDays`, `domainRegistration` | Age, registration date, expiry, registrar, status codes (RDAP); a note when the registry was not queried |
| `tls`, `httpsRedirect` | Certificate validity, issuer, dates, days left; http to https redirect |
| `emailSecurity` | MX, SPF, DMARC and its policy, nameservers |
| `blocklists` | `listed` and the hits with the list name |
| `legalPages` | For imprint, privacy, terms, returns, shipping, contact, about: found, URL, word count, template placeholders |
| `legalPagesAssessment` | AI probability that the pages are genuine, completeness 0 to 4, clear returns terms, consistent details |
| `contact` | Emails, phones, physical address probability and the exact address line from the site |
| `companyName`, `registryMatch` | Company named on the site; register match with ID, legal name, status and link |
| `platform`, `paymentMethods`, `socialLinks` | Shop platform, payment methods visible, social profile links |
| `pricing` | Products sampled, share on sale, median and max discount, AI probability that prices are unusually low (`unusualPricingProbability`) |
| `parkedSignals`, `parkedProbability` | Why the page looks parked or for sale |
| `finalUrl`, `redirectChain`, `redirectedToOtherDomain` | Where the domain ends up |
| `siteBlockedReason` | Why the website content was not read (robots.txt, bot protection, blocklist) |

A run summary with counts per status and verdict and the blocklists used (with entry counts and download time) is
saved as `SUMMARY` in the key-value store.

### How to run

1. Paste your domains or URLs into **Domains or website URLs**, one per line.
2. Keep the defaults, or turn off the AI assessment, the register lookup or the price check.
3. Optional: add a free UK Companies House API key to match UK companies.
4. Start the run and download the results as JSON, CSV or Excel, or open the **Trust check** table view.

### Example output

A real row for zalando.de (shortened):

```json
{
  "input": "zalando.de",
  "domain": "zalando.de",
  "status": "checked",
  "trustScore": 93,
  "verdict": "few_risk_signals",
  "checkCoverage": "full",
  "summary": "Few risk signals (trust score 93/100). Main positive signals: Company found in GLEIF LEI register: Zalando SE (ACTIVE); AI check: legal pages are specific to this business (probability 0.95).",
  "tls": {"valid": true, "issuer": "Let's Encrypt", "validTo": "2026-11-30", "daysLeft": 30},
  "emailSecurity": {"mx": true, "spf": true, "dmarc": true, "dmarcPolicy": "reject"},
  "blocklists": {"listed": false, "hits": []},
  "contact": {"physicalAddressProbability": 0.99, "addressLine": "Zalando SE, Valeska-Gert-Straße 5, 10243 Berlin, DE"},
  "companyName": "Zalando SE",
  "registryMatch": {"verdict": "match", "source": "GLEIF LEI register", "registryId": "529900YRFFGH5AXU4S86",
                    "legalName": "Zalando SE", "country": "DE", "registrationStatus": "ACTIVE"},
  "paymentMethods": ["Visa", "Mastercard", "American Express", "Discover", "PayPal", "Apple Pay", "Klarna", "SOFORT", "SEPA direct debit", "Bank transfer"]
}
```

A made-up shop registered four days before the check, with template legal pages and the website builder's sample
email address as contact (shortened):

```json
{
  "status": "checked",
  "trustScore": 23,
  "verdict": "many_risk_signals",
  "disclaimer": "Automated risk signals only, not a statement of fact about the merchant or its business; verify before acting.",
  "domainAgeDays": 4,
  "platform": "Wix",
  "contact": {"emails": ["info@mysite.com"]},
  "reasons": [
    {"code": "domain_age", "points": -25, "text": "Domain registered less than 30 days ago (4 days)"},
    {"code": "template_placeholders", "points": -8, "text": "Legal pages contain template placeholders such as \"info@mysite.com\""},
    {"code": "legal_genuine", "points": -8, "text": "AI check: legal pages look generic, copied or incomplete (probability genuine 0.02)"},
    {"code": "address", "points": 6, "text": "A physical business address is stated"}
  ]
}
```

### API use

Run it from your own code or an AI agent with the Apify API or the Apify MCP server:

```bash
curl -X POST "https://api.apify.com/v2/acts/reliable_tools~website-legit-checker/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["shop.example.com", "another-store.com"]}'
```

Python:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("reliable_tools/website-legit-checker").call(run_input={"domains": ["allbirds.com"]})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["domain"], row["trustScore"], row["verdict"])
```

### Pricing

Pay per event, no subscription:

| Event | Price |
|---|---|
| Website checked (all checks and the trust score) | $0.02 |
| Actor start | $0.00005 per run |

Invalid inputs, domains that are not registered and domains without a working website are **free**. Platform usage
is included in the price.

### Data sources and licences

| Source | What we use | Licence or terms |
|---|---|---|
| Domain registries over RDAP (IANA bootstrap) | Registration date, registrar, status | Public registry data service, query based: at most 100 lookups per run, paced per registry, no WHOIS, .de not queried (DENIC terms) |
| DNS | MX, SPF, DMARC, nameservers | Public DNS |
| The website itself | Homepage and up to 6 linked legal pages (10 if you raise the limit), public product catalog | Public pages, robots.txt read first and respected, honest bot name ReliableToolsBot, no proxies |
| GLEIF LEI register | Legal name, country, status | CC0 |
| UK Companies House (optional, your key) | Company name, number, status | Open Government Licence v3 |
| Phishing.Database (active phishing domains) | Domain list | MIT |
| ShadowWhisperer BlockLists (Scam, Malware) | Domain lists | Unlicense |
| durablenapkin scamblocklist | Fake shop and scam domains | MIT |

Lists that do not allow commercial use (such as the free tiers of OpenPhish, URLhaus and PhishTank) are not used.
Blocklist entries are third-party data; a listing can be outdated or wrong.

This Actor is not affiliated with or endorsed by GLEIF, DENIC, Verisign, UK Companies House, any domain registry,
the blocklist maintainers or any website it checks.

### Limits and fair use

- Up to 200 domains per run and at most 100 domain registry lookups per run. Split larger lists into several runs.
- .de domains get no registration date, because DENIC allows its registry data only for technical or administrative
  purposes.
- Websites that block bots or ask them not to crawl in robots.txt are not read; we never work around that.

### Data protection

The Actor reads public pages of the websites you enter, including imprint and contact pages. For small businesses and
sole traders these pages can contain personal data such as a name, business address, email or phone number, which
then appears in the `contact` and `companyName` fields. When the AI assessment is on, short excerpts of these public
pages are sent to our AI provider, which acts as a processor and returns probabilities only. Turn off
**AI assessment** to keep all processing on the Apify platform. Results are stored in your own Apify account, where
you control retention. Use the results only for a legitimate purpose such as merchant review, and do not republish
them as statements about named businesses or people.

### FAQ

**How do I check if a website is legit?** Enter the domain and read the `trustScore`, `verdict` and `reasons`. A new
domain, no physical address, generic legal pages, only crypto or wire transfer payments and huge discounts on brand
goods are common risk signals that deserve a closer look.

**Does a low score mean a site is a scam?** No. The score combines automated public signals to show you where to look closer.
It is not a statement of fact about any merchant. A brand new but honest shop can score low at first, and a site
behind strong bot protection can only be scored on its domain, certificate and email records.

**Why was the website content not checked for some big stores?** Some large sites block automated requests or ask
bots in robots.txt not to crawl. We respect that and never work around it, so these sites are scored on the domain
level checks only and `siteBlockedReason` says why.

**Why is the domain age missing for .de, .es or .it domains?** Some registries do not offer public RDAP, do not
publish the registration date, or (like DENIC for .de) allow their data only for technical purposes, so we do not
query them. The field then stays empty and has no effect on the score.

**Does it visit phishing sites?** No. If a domain is on one of the blocklists, no connection is made to the website at
all: no page request and no TLS check. Only DNS records and the list data are used.

**Why does a company show "not_found" in the register?** The global LEI register mostly covers larger companies and
regulated businesses. Most small shops have no LEI, so a missing record is not counted against the site.

**Does it work for any platform?** Yes. Shopify and WooCommerce stores also get a price check from their public
catalog; other sites are checked from their homepage and legal pages.

**Can I use it in an AI agent?** Yes. The input is a simple list of domains and every row has a score, a risk signal
level and plain-language reasons, which works well as a tool for shopping and payment agents.

**Something broke or a field is missing?** Open an issue on the Issues tab and we'll look at it.

### About Reliable Tools

This Actor is made by [Reliable Tools](https://apify.com/reliable_tools). We build scrapers that return clean data plus
an AI label with a confidence score, so you can filter and act on the results straight away. Our focus is e-commerce,
product sourcing and lead research.

If a field is missing or a store doesn't parse the way you expect, open an issue on the Issues tab. We read every one
and usually reply within a day. You can find our other Actors on our [profile page](https://apify.com/reliable_tools).

# Actor input Schema

## `domains` (type: `array`):

One domain or URL per line, for example shop.example.com or https://www.example.com/products/x. Each website gets a trust score from 0 to 100 with the risk signals behind it. Duplicates are checked once. Up to 200 per run.

## `aiAssessment` (type: `boolean`):

Adds AI checks with probabilities: are the legal pages genuine and complete, is a physical address stated, which company runs the site, are prices unusually low for the goods, is it a parked page.

## `checkCompanyRegistry` (type: `boolean`):

Searches the company name found on the site in the global LEI register (GLEIF), and in UK Companies House if you add a key below.

## `checkPricing` (type: `boolean`):

Reads up to 30 products from the public catalog of Shopify and WooCommerce stores (or the product markup on the homepage) to spot too-good-to-be-true discounts.

## `companiesHouseApiKey` (type: `string`):

Optional free key from the Companies House developer hub. With it, UK sites are matched against the UK company register.

## `maxLegalPages` (type: `integer`):

Imprint, contact, returns, terms, privacy, about and shipping pages linked from the homepage. Each page is one polite request.

## `concurrency` (type: `integer`):

Each website itself only gets one request at a time.

## `maxDomains` (type: `integer`):

Stops after this many domains. At most 200 per run, and at most 100 domain registry (RDAP) lookups per run, out of respect for the registries' fair-use terms. Split larger lists into several runs.

## Actor input object example

```json
{
  "domains": [
    "allbirds.com",
    "zalando.de",
    "example.com"
  ],
  "aiAssessment": true,
  "checkCompanyRegistry": true,
  "checkPricing": true,
  "maxLegalPages": 6,
  "concurrency": 8,
  "maxDomains": 100
}
```

# Actor output Schema

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

Dataset in the trust check view.

## `summary` (type: `string`):

Counts per status and verdict, and the blocklists used.

# 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 = {
    "domains": [
        "allbirds.com",
        "zalando.de",
        "example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("reliable_tools/website-legit-checker").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 = { "domains": [
        "allbirds.com",
        "zalando.de",
        "example.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("reliable_tools/website-legit-checker").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 '{
  "domains": [
    "allbirds.com",
    "zalando.de",
    "example.com"
  ]
}' |
apify call reliable_tools/website-legit-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reliable_tools/website-legit-checker"
        }
    }
}
```

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/W7Fbgg2MvYqAsV9hE/builds/zO6XWfaxOaDb1Lgah/openapi.json
