Repository navigation
API Reference
Base URL: http://localhost:8080
Auth: Header X-API-Key: <key>
Interactive docs: http://localhost:8080/docs
Starting the server:
# Bare metal
python3 __main__.py --api --host 127.0.0.1 --port 8080
# Docker (the compose service does not publish a port, so publish it at run time)
docker compose run --rm -p 8080:8080 pentestai \
python3 __main__.py --api --host 0.0.0.0Create a new API key.
Request:
{"name": "my-client"}Response:
{
"id": "key_abc123",
"name": "my-client",
"key": "psk_f3a9c...",
"created_at": "2024-01-15T10:00:00Z"
}List all API keys.
Delete an API key.
{
"name": "htb-forest",
"target": "10.10.11.162",
"description": "HackTheBox Forest machine"
}Response:
{
"session_id": "a1b2c3d4",
"name": "htb-forest",
"target": "10.10.11.162",
"created_at": "2024-01-15T10:00:00Z"
}List all sessions. Query params: ?limit=20&offset=0
Full session details including services, findings, endpoints.
Update the target or notes.
Delete the session and all related files.
List findings for the session. Query: ?severity=High&limit=50
Add a finding manually.
{
"title": "SQL Injection",
"severity": "High",
"target": "http://10.10.11.162/login",
"tool": "manual",
"description": "Login form vulnerable to SQLi",
"recommendation": "Use parameterized queries"
}Delete a finding.
Run the exploit-validation gate over every finding.
{"validated": 4, "candidate": 7, "false_positive": 1}Download findings as SARIF 2.1.0. Query: ?include_candidates=true to include
unproven findings (marked validationStatus: candidate).
Update the scope configuration.
{
"allowed_ips": ["10.10.11.0/24"],
"allowed_domains": ["forest.htb"],
"active": true
}Start a new scan.
{
"session_id": "a1b2c3d4",
"target": "10.10.11.162",
"scan_type": "recon",
"options": {
"deep": false,
"web_scan": true
}
}scan_type: recon | web | sqli | dirs | killchain | react
Response:
{
"scan_id": "scan_xyz789",
"status": "running",
"started_at": "2024-01-15T10:05:00Z"
}Scan status.
{
"scan_id": "scan_xyz789",
"status": "running",
"progress": "nmap scan in progress",
"started_at": "...",
"output_lines": 42
}status: pending | running | completed | failed | cancelled
Cancel a running scan.
Live output stream.
const ws = new WebSocket(
`ws://localhost:8080/api/v1/scans/${scanId}/stream`,
[], {headers: {"X-API-Key": apiKey}}
);
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "output") {
console.log(msg.line);
} else if (msg.type === "done") {
console.log("Scan complete");
} else if (msg.type === "heartbeat") {
// Keep-alive
}
};Configured LLM status.
{
"configured": true,
"models": [
{"provider": "anthropic", "model": "claude-sonnet-4-5", "tier": "complex", "active": true}
],
"routing_enabled": true
}Add an LLM model.
{
"provider": "groq",
"model": "llama-3.1-70b-versatile",
"api_key": "gsk_...",
"tier": "simple"
}Ask the LLM about the session.
{
"session_id": "a1b2c3d4",
"question": "What is the most likely attack vector for this target?"
}Generate a report.
{
"session_id": "a1b2c3d4",
"ai_enhanced": true,
"format": "html"
}Response:
{
"report_id": "rpt_20240115",
"format": "html",
"size_bytes": 45231,
"download_url": "/api/v1/reports/rpt_20240115/download"
}Download the report file.
Search CVEs, techniques, and findings.
Query params: ?q=log4j+jndi&top_k=10
Response:
{
"cves": [
{
"id": "CVE-2021-44228",
"cvss": 10.0,
"severity": "CRITICAL",
"desc": "Log4j2 JNDI injection allows RCE"
}
],
"techniques": [...],
"findings": [...]
}CVE details.
API_KEY="psk_..."
BASE="http://localhost:8080"
# 1. Create a session
SESSION=$(curl -s -X POST $BASE/api/v1/sessions \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"forest","target":"10.10.11.162"}' | jq -r .session_id)
# 2. Start recon
SCAN=$(curl -s -X POST $BASE/api/v1/scans \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"session_id\":\"$SESSION\",\"target\":\"10.10.11.162\",\"scan_type\":\"recon\"}" \
| jq -r .scan_id)
# 3. Wait for completion
while true; do
STATUS=$(curl -s $BASE/api/v1/scans/$SCAN \
-H "X-API-Key: $API_KEY" | jq -r .status)
echo "Status: $STATUS"
[[ "$STATUS" != "running" ]] && break
sleep 5
done
# 4. Check findings
curl -s $BASE/api/v1/sessions/$SESSION/findings \
-H "X-API-Key: $API_KEY" | jq .
# 5. Generate report
curl -s -X POST $BASE/api/v1/reports \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"session_id\":\"$SESSION\",\"ai_enhanced\":false}" | jq .