# Phishing URL Risk Scorer — URL Safety & Security Analyzer (`perryay/phishing-url-risk-scorer`) Actor

Enterprise-grade URL phishing risk analysis using 14+ detection signals. Multi-factor scoring combining URL patterns, domain analysis, SSL validation, redirect chain inspection, security header audit, and page content analysis. Ideal for automated phishing detection and SOC workflows.

- **URL**: https://apify.com/perryay/phishing-url-risk-scorer.md
- **Developed by:** [Perry AY](https://apify.com/perryay) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / actor start

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Phishing URL Risk Scorer — Multi-Signal URL Safety & Security Analysis Engine

### Phishing URL Risk Scorer — Multi-Signal URL Safety & Security Analysis Engine

**Phishing URL Risk Scorer** analyzes any URL for phishing, fraud, and security risks using **14+ independent detection signals** and produces a **normalized 0-100 risk score** with per-signal breakdown. Each signal shows exactly what was found, how much it contributed to the score, and why.

---

### What does it do?

**Phishing URL Risk Scorer** analyzes any URL for phishing, fraud, and security risks using **14+ independent detection signals** and produces a **normalized 0-100 risk score** with per-signal breakdown. Each signal shows exactly what was found, how much it contributed to the score, and why.

Whether you're triaging suspicious emails, monitoring for brand impersonation, or building automated phishing detection into your SOC pipeline — this engine handles the heavy lifting in one API call.

### Features

1. **14+ Detection Signals** — URL pattern analysis, domain reputation, TLD blacklists, brand impersonation detection, scam language patterns, raw IP detection, hex domain detection, typo-squatting, excessive subdomains, SSL validity, redirect chain analysis, security header audit, page content inspection, and credential harvesting detection
2. **Normalized Risk Scoring (0-100)** — Every signal contributes to a calibrated score. 0-15 safe, 16-30 low, 31-55 medium, 56-75 high, 76-100 critical
3. **SSL/TLS Certificate Validation** — Checks certificate validity, issuer, expiry date, days remaining, and issues warnings for expired, self-signed, or excessively long-lived certificates
4. **Redirect Chain Analysis** — Tracks every hop in the redirect chain, flags excessive redirects (>3 hops), and reports the final destination URL
5. **Deep Scan Mode** — Extended analysis with security header checking (HSTS, CSP, X-Frame-Options, X-Content-Type-Options), HTML content analysis for login forms, password fields, external form submissions, and suspicious JavaScript patterns
6. **Batch Processing** — Score up to 100 URLs in a single run with independent per-URL analysis
7. **Side-by-Side Comparison** — Compare two URLs with score difference, shared signal analysis, and risk level comparison
8. **Webhook Alert Integration** — Configure a callback URL for automated high-risk notifications

### Who is it for?

| Persona | What they use it for |
|---------|---------------------|
| **SOC Analyst** | Triage suspicious URLs reported by users — get an immediate risk score and evidence without manual investigation |
| **Security Engineer** | Automate phishing URL detection in SIEM/SOAR pipelines via API integration |
| **Brand Protection Team** | Monitor for phishing sites impersonating your domains — batch scan hundreds of reported URLs daily |
| **Threat Intelligence Analyst** | Enrich IOCs with multi-factor risk scoring and SSL/domain evidence for threat reports |
| **DevSecOps Engineer** | Incorporate URL scanning into CI/CD pipelines, webhook handlers, and email security gateways |
| **Incident Responder** | Rapidly assess phishing URLs during active incidents — compare malicious vs benign URLs side-by-side |
| **Compliance Team** | Document URL risk assessments for security audits and regulatory reporting |

### Why use this?

- **Comprehensive signal coverage** — 14+ detection signals covering URL structure, domain characteristics, SSL/TLS, network behavior, and page content. Competitors typically check 3-5 signals. This engine covers the full attack surface.
- **Transparent scoring** — Every signal includes evidence and explanation. You don't get a black-box score — you see exactly *why* a URL was flagged and *what* was found. Critical for SOC escalation reports and audit trails.
- **Production-ready API** — cURL, Python, and any HTTP client can call it. Drop it into your existing automation without SDK dependencies. Response times under 2 seconds for standard mode.
- **SSL intelligence** — Most URL checkers stop at "has SSL". This engine validates the certificate chain, checks issuer reputation, days to expiry, and flags expired or misconfigured certificates — critical for detecting advanced phishing sites with valid-but-suspicious certificates.
- **No training data needed** — All detection is based on deterministic pattern analysis and real-time SSL/network verification. Zero false-positive drift over time.

### Input Parameters

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `urls` | string | yes (or batchData) | — | One or more URLs (separate with new lines). Each URL is independently analyzed. |
| `mode` | string | no | `standard` | Analysis mode: `standard` (URL + domain + SSL) or `deep` (adds headers, content, redirects) |
| `batchMode` | boolean | no | `false` | When `true`, processes `batchData` array instead of `urls` text |
| `batchData` | array | no | — | Structured JSON array of URLs: `[{"url": "https://..."}]` |
| `compareUrl` | string | no | — | A second URL for side-by-side risk comparison |
| `alertWebhook` | string | no | — | Webhook URL called with risk report when score exceeds threshold |

### Example Input

#### Standard single URL analysis

```json
{
  "urls": "https://suspicious-site.xyz/login?redirect=banking.com",
  "mode": "standard"
}
````

#### Deep scan mode

```json
{
  "urls": "https://phishing-attempt.com/verify-account",
  "mode": "deep"
}
```

#### Batch processing

```json
{
  "urls": "https://example.com\nhttps://example.org/login\nhttps://example.net",
  "mode": "standard"
}
```

#### Side-by-side comparison

```json
{
  "urls": "https://google.com",
  "compareUrl": "https://google.com.secure-login.xyz"
}
```

### Output Format

| Field | Type | Description |
|-------|------|-------------|
| `url` | string | The analyzed URL |
| `risk_score` | integer | Normalized risk score 0-100 |
| `risk_level` | string | Classification: safe, low, medium, high, critical |
| `signals` | array | Full list of detected signals with evidence |
| `signal_count` | integer | Number of positive (risky) signals detected |
| `has_ssl` | boolean | Whether the server supports HTTPS |
| `ssl_valid` | boolean | Whether the SSL certificate passed verification |
| `redirect_count` | integer | Number of HTTP redirect hops |
| `redirect_chain` | array | Full chain of URLs through all redirects |
| `final_url` | string | Destination URL after all redirects |
| `analysis_time_ms` | number | Processing time in milliseconds |
| `error` | string | Error message if analysis failed |

### Example Output

```json
{
  "url": "https://suspicious-site.xyz/login?redirect=banking.com",
  "risk_score": 78,
  "risk_level": "high",
  "signals": [
    {
      "name": "auth_keywords",
      "severity": "high",
      "score_delta": 15,
      "description": "Auth-related keywords (phishing bait)",
      "evidence": "/login?redirect=banking.com"
    },
    {
      "name": "suspicious_tld",
      "severity": "high",
      "score_delta": 18,
      "description": "Suspicious TLD: .xyz. Free TLDs are commonly used for phishing",
      "evidence": "suspicious-site.xyz"
    },
    {
      "name": "brand_impersonation",
      "severity": "high",
      "score_delta": 18,
      "description": "Known brand impersonation target",
      "evidence": "redirect=banking.com"
    }
  ],
  "signal_count": 3,
  "has_ssl": true,
  "ssl_valid": false,
  "redirect_count": 2,
  "final_url": "https://phishing-server.com/credentials.php",
  "analysis_time_ms": 1432.5
}
```

### API Usage

#### cURL

```bash
## Analyze a single URL
curl -X POST "https://api.apify.com/v2/acts/perryay~phishing-url-risk-scorer/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": "https://suspicious-site.xyz/login",
    "mode": "deep"
  }'

## Batch analyze multiple URLs
curl -X POST "https://api.apify.com/v2/acts/perryay~phishing-url-risk-scorer/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": "https://example.com\nhttps://example.org",
    "mode": "standard"
  }'

## Compare two URLs
curl -X POST "https://api.apify.com/v2/acts/perryay~phishing-url-risk-scorer/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": "https://google.com",
    "compareUrl": "https://google.com.phishing-site.xyz"
  }'
```

#### Python

```python
import requests

API_TOKEN = "YOUR_API_TOKEN"
ACTOR_URL = "https://api.apify.com/v2/acts/perryay~phishing-url-risk-scorer/runs"

## Analyze single URL with deep mode
response = requests.post(
    ACTOR_URL,
    headers={"Content-Type": "application/json",
             "Authorization": f"Bearer {API_TOKEN}"},
    json={"urls": "https://suspicious-site.xyz", "mode": "deep"}
)
result = response.json()

if result["risk_level"] in ("high", "critical"):
    print(f"🚨 HIGH RISK: {result['risk_score']}/100")
    for signal in result["signals"]:
        print(f"  - {signal['description']}: {signal['evidence']}")
else:
    print(f"✅ Safe: {result['risk_score']}/100")

## Batch analyze and filter risky ones
response = requests.post(
    ACTOR_URL,
    headers={"Content-Type": "application/json",
             "Authorization": f"Bearer {API_TOKEN}"},
    json={
        "urls": "https://example.com\nhttps://phishing.xyz\nhttps://legit-site.com",
        "mode": "standard"
    }
)
results = response.json().get("results", [])

risky_urls = [r for r in results if r.get("risk_level") in ("high", "critical")]
print(f"Found {len(risky_urls)} risky URLs out of {len(results)}")
```

### Use Cases

1. **SOC Email Triage** — Your SOC receives hundreds of reported phishing emails daily. Automate URL risk scoring to prioritise high-risk URLs for immediate analyst review. URLs scoring 56+ (high/critical) get escalated; safe URLs are automatically closed with a report.

2. **Brand Protection Monitoring** — Monitor hundreds of reported lookalike domains daily. Batch scan all of them through this engine and get risk-scored, evidence-backed reports. Auto-escalate domains that score critical with brand impersonation + invalid SSL signals.

3. **Webhook Security Gateway** — Deploy as a webhook endpoint that incoming URLs automatically route through before delivery to users. If the risk score exceeds a configurable threshold, the URL is blocked and the security team is alerted.

4. **Incident Investigation** — During an active phishing incident, quickly assess all IOCs (Indicator of Compromise) by running them through the engine. The side-by-side comparison mode helps distinguish genuine URLs from phishing URLs that closely mimic legitimate ones.

5. **Compliance Documentation** — Generate risk-scored URL assessments for security audits. Each output includes timestamps, signal evidence, and SSL validation details — suitable for inclusion in regulatory compliance reports (PCI-DSS, SOC2, ISO 27001).

### FAQ

**Q: What makes this different from a simple URL blacklist check?**
A: Blacklists only catch known-bad URLs. This engine analyzes URL *structure*, domain *characteristics*, SSL *validity*, and page *content* — catching never-before-seen phishing URLs based on behavioural patterns. A brand-new phishing site on a .xyz domain with an invalid SSL and auth keywords in the URL will score high even if no security vendor has seen it before.

**Q: Can I process more than 100 URLs?**
A: The per-run limit is 100 URLs. For larger workloads, split into batches and run them sequentially or in parallel (the Apify platform supports concurrent runs). Each run is independent.

**Q: What is the difference between standard and deep mode?**
A: Standard mode analyzes URL patterns, domain characteristics, and SSL/TLS validity — completing in under 2 seconds per URL. Deep mode additionally fetches the page content to check for login forms, password fields submitting to external domains, suspicious JavaScript, and security HTTP headers — taking 3-8 seconds per URL. Use standard for bulk triage, deep for high-priority investigations.

**Q: Are there any false positives?**
A: The deterministic (non-ML) engine avoids the false-positive drift common with AI-based detectors. Every signal has a specific, explainable trigger. URL shorteners and raw IP addresses in legitimate URLs will score slightly higher, which is by design — these *are* risk indicators, even if the specific URL happens to be benign.

**Q: Can I integrate this with my SIEM?**
A: Yes. The structured JSON output is SIEM-friendly. Use the cURL or Python API to submit URLs and ingest results into Splunk, Elastic, QRadar, or any JSON-capable SIEM. The `risk_score` field can be used for correlation rules.

**Q: Does this check against VirusTotal or other threat intelligence feeds?**
A: Not directly. This is a deterministic risk scoring engine — it doesn't query external threat intel feeds. For enrichment, pipe the output into your existing threat intel platform (TIP) which can correlate with VirusTotal, AlienVault OTX, or MISP.

**Q: What happens if the target URL is down or times out?**
A: The engine still performs URL pattern analysis and domain analysis even if the server is unreachable. SSL and content checks are skipped gracefully with a note in the output. You still get a partial risk assessment based on what could be analyzed.

**Q: How is SSL certificate validation performed?**
A: Using Python's built-in SSL context with certificate verification enabled (CERT\_REQUIRED). The engine establishes a real TLS connection to the server, retrieves and validates the certificate chain, extracts issuer, subject, and expiry information, and checks for common issues like expired certificates, self-signed certs, and certificates valid for longer than 825 days (CA/Browser Forum baseline requirements).

**Q: Does this support internationalized domain names (IDN)?**
A: Yes. IDN homograph attacks (using visually similar Unicode characters) are partially covered — the engine checks for mixed character classes and flags hex-like patterns.

**Q: Does the redirect chain analysis slow down execution?**
A: Redirect analysis is lightweight by default (up to 3 hops). If a URL chain exceeds 3 redirects, the analysis stops and flags it. The redirect tracking adds at most 200-500ms per hop. In standard mode, this is included in the <2s typical per-URL time.

***

### Usage & Billing

This actor uses Apify's **PAY\_PER\_EVENT** pricing model. You are charged only for successful runs based on the events your usage triggers.

#### Charge Events

| Event | Trigger |
|-------|--------|
| `apify-actor-start` | Every run (base) |
| `deep-scan` | Single URL in `deep` mode (includes content fetching) |
| `batch-check` | Batch mode with 5+ URLs |

Platform costs (Apify's infrastructure fee) are passed through to the customer.

***

### MCP Integration

This actor can be used through the [Apify MCP server](https://docs.apify.com/integrations/mcp). Once connected, your MCP client (Claude Desktop, Cursor, etc.) can discover and run this actor from the Apify Store.

#### Quick Start

1. **Install the Apify connector** in your MCP client:
   - **Claude Desktop**: Search for "Apify" in the connector directory, or use the remote server at `https://mcp.apify.com`
   - **Other clients**: See the [Apify MCP server docs](https://docs.apify.com/integrations/mcp) for setup instructions

2. **Ask your AI assistant** to analyze URLs for phishing risk. For example:
   > "Analyze https://suspicious-site.xyz for phishing risk"
   > "Compare https://google.com and https://google.com.phishing-site.xyz side by side"

#### Claude Desktop Configuration

Add the following to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com"
    }
  }
}
```

On first connection, your browser opens to sign in to Apify and authorize access.

> **Bearer token alternative:** For headless environments, CI/CD pipelines, or clients without browser-based OAuth, you can authenticate directly with your Apify API token:
>
> ```json
> {
>   "mcpServers": {
>     "apify": {
>       "url": "https://mcp.apify.com",
>       "headers": {
>         "Authorization": "Bearer YOUR_APIFY_TOKEN"
>       }
>     }
>   }
> }
> ```
>
> Get your API token from [Apify Console](https://console.apify.com) → **API & Integrations** section.

***

### Related Tools

- [Domain Intel](https://apify.com/perryay/domain-intel) — WHOIS lookups, DNS enumeration, and SSL certificate validation for any domain
- [SSL Certificate Checker](https://apify.com/perryay/ssl-certificate-checker) — Check SSL/TLS certificate validity, issuer, and expiry details for any domain
- [Link Quality Analyzer](https://apify.com/perryay/link-quality-analyzer) — Deep link health and quality scoring for SEO and content auditing
- [URL Health Checker](https://apify.com/perryay/url-health) — URL availability, HTTP status, and SSL health monitoring with batch support
- [Meta Mate](https://apify.com/perryay/meta-mate) — Extract Open Graph, Twitter Cards, and JSON-LD metadata from URLs
- [Brand Monitor Lite](https://apify.com/perryay/brand-monitor-lite) — Track brand mentions across multiple URLs for brand protection

# Actor input Schema

## `urls` (type: `string`):

One or more URLs to score for phishing risk. Separate multiple URLs with new lines. Supports http:// and https:// schemes. In batch mode, each line is processed independently.

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

Standard: URL pattern analysis + domain analysis + SSL validation. Deep: includes security header audit, page content analysis, and redirect chain inspection.

## `batchMode` (type: `boolean`):

Enable to process URLs as a structured JSON array with individual objects per URL

## `batchData` (type: `array`):

Array of URL objects for structured batch processing. Each object must have a 'url' field. Optional fields: 'mode' for per-URL mode override.

## `compareUrl` (type: `string`):

A second URL to compare against the first URL. Produces a side-by-side risk comparison showing score differences and shared signals.

## `alertWebhook` (type: `string`):

Optional webhook URL for high-risk alerts. When a URL scores 'high' or 'critical', a POST notification is sent to this endpoint with the risk report.

## Actor input object example

```json
{
  "urls": "https://example.com\nhttps://suspicious-site.xyz/login",
  "mode": "standard",
  "batchMode": false,
  "batchData": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://phishing-test.com/login"
    }
  ]
}
```

# Actor output Schema

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

Phishing risk analysis results in the default dataset — one item per analyzed URL

# 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 = {
    "urls": `https://example.com
https://suspicious-site.xyz/login`,
    "batchData": [
        {
            "url": "https://example.com"
        },
        {
            "url": "https://phishing-test.com/login"
        }
    ],
    "compareUrl": "",
    "alertWebhook": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("perryay/phishing-url-risk-scorer").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 = {
    "urls": """https://example.com
https://suspicious-site.xyz/login""",
    "batchData": [
        { "url": "https://example.com" },
        { "url": "https://phishing-test.com/login" },
    ],
    "compareUrl": "",
    "alertWebhook": "",
}

# Run the Actor and wait for it to finish
run = client.actor("perryay/phishing-url-risk-scorer").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "urls": "https://example.com\\nhttps://suspicious-site.xyz/login",
  "batchData": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://phishing-test.com/login"
    }
  ],
  "compareUrl": "",
  "alertWebhook": ""
}' |
apify call perryay/phishing-url-risk-scorer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=perryay/phishing-url-risk-scorer",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Phishing URL Risk Scorer — URL Safety & Security Analyzer",
        "description": "Enterprise-grade URL phishing risk analysis using 14+ detection signals. Multi-factor scoring combining URL patterns, domain analysis, SSL validation, redirect chain inspection, security header audit, and page content analysis. Ideal for automated phishing detection and SOC workflows.",
        "version": "1.0",
        "x-build-id": "Si4LuqbVzUSYMiPMP"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/perryay~phishing-url-risk-scorer/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-perryay-phishing-url-risk-scorer",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/perryay~phishing-url-risk-scorer/runs": {
            "post": {
                "operationId": "runs-sync-perryay-phishing-url-risk-scorer",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/perryay~phishing-url-risk-scorer/run-sync": {
            "post": {
                "operationId": "run-sync-perryay-phishing-url-risk-scorer",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "urls": {
                        "title": "URL(s) to Analyze",
                        "type": "string",
                        "description": "One or more URLs to score for phishing risk. Separate multiple URLs with new lines. Supports http:// and https:// schemes. In batch mode, each line is processed independently."
                    },
                    "mode": {
                        "title": "Analysis Mode",
                        "enum": [
                            "standard",
                            "deep"
                        ],
                        "type": "string",
                        "description": "Standard: URL pattern analysis + domain analysis + SSL validation. Deep: includes security header audit, page content analysis, and redirect chain inspection.",
                        "default": "standard"
                    },
                    "batchMode": {
                        "title": "Batch Mode",
                        "type": "boolean",
                        "description": "Enable to process URLs as a structured JSON array with individual objects per URL",
                        "default": false
                    },
                    "batchData": {
                        "title": "Batch URL Data",
                        "type": "array",
                        "description": "Array of URL objects for structured batch processing. Each object must have a 'url' field. Optional fields: 'mode' for per-URL mode override."
                    },
                    "compareUrl": {
                        "title": "Compare URL",
                        "type": "string",
                        "description": "A second URL to compare against the first URL. Produces a side-by-side risk comparison showing score differences and shared signals."
                    },
                    "alertWebhook": {
                        "title": "Alert Webhook URL (Monitor Mode)",
                        "type": "string",
                        "description": "Optional webhook URL for high-risk alerts. When a URL scores 'high' or 'critical', a POST notification is sent to this endpoint with the risk report."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
