Documentation beta
How to use the scanner — the web app and the JSON API. Results are informational only, produced by automated tests.
Beta access beta
During the closed beta the scanner is invite-only. You need a personal
access code — it looks like bk-…. No code yet?
Request beta access.
Web app beta
- Magic link (easiest) — open the invite link
https://scan.stalkphish.io/?code=bk-yourcode. Your code is remembered on this browser and the code is stripped from the address bar. Nothing else to do. - Or enter it by hand — on the Scan page, type your code in the “Closed beta” box and press Enter.
- Your code is kept in a secure, http-only cookie, so you won't be re-prompted on this browser until it expires. If a scan later reports invalid access, your code was revoked or expired — just re-enter it.
API beta
Send your code on every request, in either header
(X-Access-Key or a Bearer token):
curl -s -X POST https://scan.stalkphish.io/api/scan \
-H 'Content-Type: application/json' \
-H 'X-Access-Key: bk-yourcode' \
-d '{"url":"https://suspicious-example.com/login"}'
# equivalently:
# -H 'Authorization: Bearer bk-yourcode'| Response | Meaning |
|---|---|
202 | Accepted — a scan was queued. |
401 | Missing, invalid, or revoked access code. |
429 | Your code's quota is spent — see the Retry-After header. |
Each code has its own quota. Please scan responsibly, and use “⚑ Report a false positive or issue” on any wrong verdict — that feedback is exactly what the beta is for.
Using the web app
- Paste a URL on the Scan page and press Scan URL.
Defanged URLs are accepted —
hxxps://evil[.]comis read ashttps://evil.com. If you omit the scheme,https://is assumed. - The scan runs asynchronously. You are taken to a result page that updates live: Queued… → the current phase (Resolving DNS & hosting, Querying threat intelligence, Fetching & analysing the page, Rendering the page…) → the final result.
- Under heavy load a submission may be rejected with a “scanner is busy” message — retry in a moment.
The web app never fetches the target from your browser. The URL is analysed from isolated infrastructure, through proxies — your IP is never used.
Reading a result
The header shows a score out of 100 and a verdict:
| Verdict | Score | Meaning |
|---|---|---|
| CRITICAL | 80–100 | Almost certainly phishing. |
| HIGH | 55–79 | Strong phishing indicators. |
| MEDIUM | 35–54 | Suspicious — investigate further. |
| LOW | 18–34 | Weak signals. |
| VERY LOW | 0–17 | No significant indicators. |
The report is organised in sections:
- Screenshot — a snapshot of the page rendered from isolated infrastructure (not a live page).
- Detections — the scored signals that fired (generic labels; the exact detection logic is intentionally not exposed).
- StalkPhish.io Threat intelligence — IP reputation — shown only when the resolved IP is already known for hosting other phishing.
- HTTP redirect chain, Network, HTTP, TLS certificate, Domain / WHOIS, Threat intel — StalkPhish — forensic metadata.
Every hostile URL is shown defanged (hxxp://…[.]…) so it can't be
clicked by accident. Each result also carries the scan time (UTC).
Think a verdict is wrong? Use “⚑ Report a false positive or issue” at the bottom of the result — it attaches the exact scan so we can reproduce and tune.
Limits & privacy
- Rate limit — submissions are capped per IP; over the limit returns “Too many scans from your network” (HTTP 429).
- Ephemeral — results live for a limited time and are shared only via their
unique link (
/results/<uuid>), which search engines don't index. - No warranty — results come from automated tests, are not a definitive verdict, and are provided without warranty. Always verify independently.
API
Everything the web app does is available over a JSON API. The interactive reference is Swagger UI:
beta Authentication required.
Every POST /api/scan needs your access code
(X-Access-Key: bk-…) — see Beta access above.
Open API reference (Swagger) → OpenAPI schema
Asynchronous flow
A scan is a job: submit a URL, receive a uuid, then poll until it's done.
| Method | Path | Purpose |
|---|---|---|
| POST | /api/scan | Submit a URL → 202 {uuid, status:"queued"} |
| GET | /api/scan/{uuid} | Status & result (queued → running → done | error) |
| GET | /api/scan/{uuid}/screenshot | Rendered screenshot (PNG) |
| POST | /api/report | Report a false positive / issue on a scan |
Example
# 1. Submit — returns a UUID immediately
curl -s -X POST https://scan.stalkphish.io/api/scan \
-H 'Content-Type: application/json' \
-d '{"url":"https://suspicious-example.com/login"}'
# → {"uuid":"a1b2c3d4-...","status":"queued"}
# 2. Poll until status == "done"
curl -s https://scan.stalkphish.io/api/scan/a1b2c3d4-...
# → {"status":"done","result":{"score":92,"verdict":"CRITICAL", ... }}
# 3. (optional) fetch the screenshot
curl -s https://scan.stalkphish.io/api/scan/a1b2c3d4-.../screenshot -o shot.pngThe edge only enqueues — it never fetches the target itself
(SSRF containment). Responses 429 (per-IP quota) and 503
(scanner busy) mean “retry later”. Defanged URLs are accepted.
Results come from automated tests, for information only and without warranty. They may be inaccurate and are not a definitive verdict — StalkPhish.io accepts no liability; always verify independently.