API Documentation
HTSBP provides a free, open REST API and MCP server for checking domains and URLs against our threat intelligence database of indirect prompt injection (IDPI) attacks.
https://hasthissitebeenpoisoned.ai/api
check-domain
/api/check-domain?domain={domain}
Check if a domain hosts known IDPI attacks targeting AI agents.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| domain | string | Yes | Domain to check |
curl -s "https://hasthissitebeenpoisoned.ai/api/check-domain?domain=reviewerpress.com" | jq .
Response (malicious)
{
"domain": "reviewerpress.com",
"is_malicious": true,
"threats": [
{
"severity": "critical",
"intent": "ad_review_bypass",
"techniques": ["zero_font_size", "css_display_none"],
"description": "First known real-world AI ad review bypass...",
"source": "unit42",
"first_seen": "2025-12-15T00:00:00Z",
"last_seen": "2026-03-03T00:00:00Z",
"is_active": true
}
]
}
Response (not found)
{
"domain": "example.com",
"is_malicious": false,
"threats": []
}
list-threats
/api/list-threats
List known IDPI threats with optional filters. All parameters are optional.
| Name | Type | Default | Description |
|---|---|---|---|
| severity | string | — | critical, high, medium, low |
| intent | string | — | Filter by attack intent |
| limit | number | 20 | Max results (1–50) |
| offset | number | 0 | Pagination offset |
curl -s "https://hasthissitebeenpoisoned.ai/api/list-threats?severity=critical&limit=10" | jq .
stats
/api/stats
Returns aggregate statistics about the threat database.
curl -s "https://hasthissitebeenpoisoned.ai/api/stats" | jq .
report-threat
/api/report-threat
Submit a suspected IDPI threat. Opens a Pull Request which is automatically validated by the same scan + research pipeline used for human PRs (observation 1: reachability + AI malicious code analysis; observation 2: source_url credibility + domain reputation via web search). Returns the PR URL — the threat is registered only after a reviewer merges the PR.
Request Body (JSON)
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL where the IDPI payload was observed (http/https) |
| source_url | string | Yes | URL of the supporting evidence/citation (article, IoC, blog post) |
| description | string | Yes | What was observed (location of hidden instructions, wording, behavior — min 20 chars) |
| severity | string | No | Submitter's estimate (critical / high / medium / low). Re-derived by scan. |
curl -X POST "https://hasthissitebeenpoisoned.ai/api/report-threat" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/suspicious",
"source_url": "https://researcher.example.com/2026/idpi-report",
"description": "Hidden <div style=font-size:0> in the footer with prompt-injection text targeting AI agents",
"severity": "high"
}'
Response (201 Created)
{
"success": true,
"message": "PR を起票しました。pr-validate ワークフローが自動検証を実行します。",
"pr_url": "https://github.com/tanbablack/htsbp/pull/123",
"pr_number": 123,
"branch": "report/example.com-1714000000000",
"host": "example.com"
}
Error responses
400— invalid url / source_url / description / severity (returned with{ error: <field>, message })405— wrong HTTP method500— GitHub API or internal error
MCP Server
Connect your AI tools directly to HTSBP threat intelligence via the Model Context Protocol.
Connection Guide
Add this to your MCP client configuration (Claude Desktop, Cursor, Windsurf, etc.):
{
"mcpServers": {
"htsbp": {
"url": "https://hasthissitebeenpoisoned.ai/api/mcp"
}
}
}
Available Tools
check_domain
Check if a domain hosts known IDPI attacks targeting AI agents.
Input: { domain: string }
list_threats
List known IDPI threats with optional filters.
Input: { severity?: string, intent?: string, limit?: number }
report_threat
Submit a suspected IDPI threat. Opens a Pull Request that is automatically validated by the same scan + research pipeline used for human PRs. Returns the PR URL.
Input: { url: string, source_url: string, description: string, severity?: string }
Example Conversations
Sample Scripts
Python
import requests
def check_domain(domain: str) -> dict:
resp = requests.get(
"https://hasthissitebeenpoisoned.ai/api/check-domain",
params={"domain": domain}
)
return resp.json()
def is_safe(url: str) -> bool:
from urllib.parse import urlparse
domain = urlparse(url).netloc
result = check_domain(domain)
return not result.get("is_malicious", False)
result = check_domain("reviewerpress.com")
print(f"Malicious: {result['is_malicious']}")
for threat in result.get("threats", []):
print(f" - [{threat['severity']}] {threat['intent']}: {threat['description']}")
Node.js / TypeScript
const HTSBP_BASE = "https://hasthissitebeenpoisoned.ai/api";
async function checkDomain(domain: string) {
const res = await fetch(`${HTSBP_BASE}/check-domain?domain=${encodeURIComponent(domain)}`);
return res.json();
}
const result = await checkDomain("cblanke2.pages.dev");
if (result.is_malicious) {
console.warn(`BLOCKED: ${result.threats[0].description}`);
}
cURL
curl -s "https://hasthissitebeenpoisoned.ai/api/check-domain?domain=reviewerpress.com" | jq .
curl -s "https://hasthissitebeenpoisoned.ai/api/list-threats?severity=critical&limit=10" | jq .
curl -s "https://hasthissitebeenpoisoned.ai/api/stats" | jq .
MCP Client (TypeScript)
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://hasthissitebeenpoisoned.ai/api/mcp")
);
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool("check_domain", { domain: "reviewerpress.com" });
console.log(result);
Report a Threat
Found a website with hidden prompt injection targeting AI agents? Choose any of the three equivalent paths — all go through the same validation pipeline (scan + research) and require a reviewer to merge before the threat is registered.
POST /api/report-threatreport_threatdata/threats/domains/Path A: REST API
Send POST /api/report-threat with a JSON body. The API opens a PR on your behalf and returns the PR URL. Full schema in the report-threat endpoint docs.
curl -X POST "https://hasthissitebeenpoisoned.ai/api/report-threat" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/suspicious",
"source_url": "https://researcher.example.com/2026/idpi-report",
"description": "Hidden <div style=font-size:0> in the footer with prompt-injection text targeting AI agents",
"severity": "high"
}'
Path B: MCP Tool
Call the report_threat tool from any MCP client (Claude Desktop, Cursor, Windsurf, etc.). Same underlying flow as the REST API.
await client.callTool("report_threat", {
url: "https://example.com/suspicious",
source_url: "https://researcher.example.com/2026/idpi-report",
description: "Hidden div in the footer with prompt-injection text targeting AI agents",
severity: "high"
});
// → { pr_url, pr_number, branch, host }
Path C: Direct Pull Request
Edit data/threats/domains/<host>.json directly on GitHub.
{
"domain": "example.com",
"threats": [
{
"url": "https://example.com/suspicious",
"severity": "high",
"intent": "other",
"techniques": [],
"description": "Hidden div in the footer with prompt-injection text targeting AI agents",
"source": "community",
"source_url": "https://researcher.example.com/2026/idpi-report",
"first_seen": "2026-04-25T00:00:00Z",
"last_seen": "2026-04-25T00:00:00Z",
"is_active": true
}
],
"updated_at": "2026-04-25T00:00:00Z"
}
All three paths require the same fields:
- The full URL where the IDPI payload was observed
source_url— citation to the original report or evidence (required)- A description of the hidden instructions or behavior (≥ 20 chars for API/MCP)
- (Optional) Your estimated
severity(critical / high / medium / low) — the scan pipeline re-derives the final value
The PR validation workflow runs our shared scan + research libraries and posts the verdict as a PR comment. Entries without a credible source_url or that are unreachable + unverifiable will fail CI and cannot be merged.