Detect phishing
Paste a message that says your account will close today unless you log in, and you get a risk score plus the exact signals found: urgency, a borrowed brand look, a request for your password. Pay per use, no subscription.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
A phishing email rarely announces itself; it borrows a familiar logo, a plausible sender name and a reason to act now.
How phishing slips past a quick look
A phishing message rarely announces itself. It borrows a familiar logo, a believable sender name and a reason to act right now. Lists of known bad websites catch old scams, but a lookalike domain registered yesterday will not be on any list yet. This check reads the content, structure and framing of the email or page instead. It looks for invented urgency, imitation of a recognisable brand, requests for login or payment details, a display name that does not match the sender, and link text that hides a different destination.
Reading the score and its signals
You get a risk score together with the specific signals that raised it, not a single unexplained number. That matters when you have to decide quickly: you can see that a message is risky because it asks for your password and links somewhere other than it claims. Use it to sort incoming mail into quarantine above a threshold, or to give a customer a second opinion before they reply or click. People spot phishing well when they are rested and paying attention; the check helps when they are tired or rushed.
The gap this closes
URL reputation checks catch known-bad domains, but a freshly registered lookalike domain sailing a brand-new phishing kit will not appear on any blocklist yet. Content-level signals catch attacks that pure reputation lookups miss entirely.
What you can do with it
Inbound mail scoring
Score every message before it lands in a user's inbox, routing anything above a risk threshold to quarantine instead of the primary folder.
Support-desk second opinions
Let customers paste a suspicious message into a support form and get an immediate risk read before they reply or click anything inside it.
FAQ
What formats can I submit?
Raw email content or page content as text; the task reads the message body, sender framing and any embedded structure you provide.
How accurate is the risk score?
The score reflects concrete, disclosed signals such as urgency language, sender mismatches and credential requests rather than a proprietary black-box number, so you can see exactly why a message was flagged.
Is the submitted email content stored?
No, content is deleted after the retention window and is never used to train models.
Can it catch phishing from a brand-new website?
Yes, because it reads what the message or page is doing rather than checking a blocklist. A freshly registered lookalike domain is not on any list yet, but its urgent tone and request for your login still give it away.
What warning signs does the phishing check look for?
Pressure to act now, imitation of a known brand’s look, requests for passwords or card details, a sender name that does not match the real address, and links whose visible text points somewhere other than their real destination.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/verify/phishing \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"El informe trimestral cerró con 1,2 M€ de ingresos."}'const res = await fetch("https://api.kit.forhosting.com/verify/phishing", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "El informe trimestral cerró con 1,2 M€ de ingresos."
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/verify/phishing",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "El informe trimestral cerró con 1,2 M€ de ingresos."
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/verify/phishing", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"El informe trimestral cerró con 1,2 M€ de ingresos."}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"El informe trimestral cerró con 1,2 M€ de ingresos."}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/verify/phishing", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "El informe trimestral cerró con 1,2 M€ de ingresos."
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "verify.phishing",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |
Technical notes
The phishing risk API reads the actual content, structure and framing of an email or page and returns a risk score with the signals behind it, so your inbox or intake pipeline can act before a human has to make that judgment call under pressure.
The gap this closes
This endpoint instead reads what the message or page is actually doing: does it manufacture urgency, impersonate a recognizable brand's visual language, ask for credentials or payment details, or use the mismatch between a displayed link text and its real target that has been a phishing staple since the earliest email scams.
Who this is built for
Mail platforms scoring inbound messages before delivery, customer-support tools screening forwarded 'is this real?' emails, security teams triaging a flood of reported messages, and SaaS products that let users paste a suspicious email or page for a second opinion all use this endpoint for the same underlying reason: humans are good at spotting phishing when they're paying attention, and bad at it when they're tired, rushed or targeted specifically because the message looks routine.
What you send and what comes back
Submit to POST /verify/phishing the email content or page content you want scored, and the task evaluates linguistic urgency markers, sender/display-name mismatches, requests for sensitive information, and structural impersonation patterns, returning a score alongside the specific signals detected rather than a single opaque number. That transparency matters because a security team acting on the verdict needs to know why, not just what.
Built for volume, priced for it too
The task runs asynchronously at $0.003 per request plus $0.0135 per item scored, and failed evaluations are never billed, with three automatic retries before a clear error is returned. Results arrive by signed webhook, the recommended path for automated triage, or through a signed link valid 24 hours for teams reviewing flagged items manually before closing a ticket.
Where it sits next to other checks
Running both against the same message gives you a content-level verdict and a link-level verdict independently, which is a more resilient combination than either check alone since attackers who defeat one layer often trip the other. Phishing scoring reads content and framing; it does not itself resolve or reputation-check embedded links, which is exactly what verify.url_safe is for.
Integration use cases
Reported-email triage
Run every user-forwarded 'suspicious email' through the endpoint automatically so a security analyst reviews a ranked queue instead of a raw pile.
Brand-impersonation monitoring
Feed pages that mimic your product's login screen into the endpoint to confirm phishing framing before requesting a takedown.
Technical questions
Is the phishing detection API free to use?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How is the phishing check priced?
$0.003 per request plus $0.0135 per item scored, charged only on a completed, successful task.
Does it check the links inside the message too?
It evaluates content-level phishing signals; pair it with verify.url_safe to also resolve and reputation-check any links found inside the message.
Can I run this on a batch of reported emails?
Yes, submit each message as its own request; every call returns an independent task_id and result, which suits high-volume triage queues well.
How do I receive results?
Via signed webhook, recommended for automated pipelines, or a signed link valid for 24 hours for manual review workflows.