Zen-AI-Pentest API Documentation
July 24, 2026 · View on GitHub
Version: 3.0.0
OpenAPI: 3.0.3
Base URL:http://localhost:8000/api/v1
Last Updated: 2026-03-31
Overview
The Zen-AI-Pentest API provides a comprehensive REST interface for managing penetration testing operations. Built with FastAPI, it offers automatic OpenAPI documentation, type validation, and high performance.
Features
- ✅ OpenAPI 3.0 - Auto-generated interactive documentation
- ✅ JWT Authentication - Secure token-based access
- ✅ Rate Limiting - Per-user and per-endpoint throttling
- ✅ WebSocket Support - Real-time scan updates
- ✅ Request/Response Validation - Pydantic v2 models
- ✅ Pagination - Standard cursor and offset pagination
- ✅ Filtering & Sorting - Query parameter support
Quick Start
1. Authentication
# Get access token
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=admin"
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
"token_type": "bearer",
"expires_in": 3600
}
2. Make Authenticated Request
export TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6..."
curl -X GET http://localhost:8000/api/v1/scans \
-H "Authorization: Bearer $TOKEN"
3. Interactive Documentation
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
Authentication
Login
Authenticate and receive a JWT access token.
POST /api/v1/auth/login
Content-Type: application/x-www-form-urlencoded
username={username}&password={password}
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
username | string | Yes | User login name |
password | string | Yes | User password |
Response (200 OK):
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}
Error Responses:
| Status | Code | Description |
|---|---|---|
| 401 | INVALID_CREDENTIALS | Username or password incorrect |
| 403 | ACCOUNT_LOCKED | Account temporarily locked |
| 429 | RATE_LIMIT_EXCEEDED | Too many login attempts |
Token Refresh
Refresh an expiring access token.
POST /api/v1/auth/refresh
Authorization: Bearer {refresh_token}
Response (200 OK):
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
"token_type": "bearer",
"expires_in": 3600
}
Logout
Revoke the current access token.
POST /api/v1/auth/logout
Authorization: Bearer {access_token}
Response (204 No Content)
Current User
Get information about the authenticated user.
GET /api/v1/auth/me
Authorization: Bearer {access_token}
Response (200 OK):
{
"id": 1,
"username": "admin",
"email": "admin@example.com",
"full_name": "Administrator",
"role": "admin",
"permissions": ["scans:read", "scans:write", "tools:execute"],
"created_at": "2026-01-15T10:00:00Z",
"last_login": "2026-03-31T08:30:00Z"
}
Scans
List Scans
Retrieve all scans with pagination and filtering.
GET /api/v1/scans?skip=0&limit=20&status=running&sort=-created_at
Authorization: Bearer {access_token}
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
skip | integer | 0 | Number of records to skip |
limit | integer | 20 | Maximum records to return (max: 100) |
status | string | - | Filter by status: pending, running, completed, failed, cancelled |
scan_type | string | - | Filter by type: network, web, api, compliance |
target | string | - | Filter by target (partial match) |
created_after | datetime | - | Filter by creation date (ISO 8601) |
created_before | datetime | - | Filter by creation date (ISO 8601) |
sort | string | -created_at | Sort field, prefix - for descending |
Response (200 OK):
{
"total": 156,
"skip": 0,
"limit": 20,
"data": [
{
"id": 123,
"name": "Production Network Scan",
"target": "192.168.1.0/24",
"scan_type": "network",
"status": "running",
"risk_level": 2,
"progress": 45,
"findings_count": 12,
"created_at": "2026-03-31T10:00:00Z",
"started_at": "2026-03-31T10:05:00Z",
"estimated_completion": "2026-03-31T11:00:00Z",
"created_by": {
"id": 1,
"username": "admin"
}
}
],
"links": {
"self": "/api/v1/scans?skip=0&limit=20",
"next": "/api/v1/scans?skip=20&limit=20",
"prev": null
}
}
Rate Limit Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1711881600
Create Scan
Start a new penetration test scan.
POST /api/v1/scans
Authorization: Bearer {access_token}
Content-Type: application/json
{
"name": "Web Application Security Assessment",
"target": "https://example.com",
"scan_type": "web",
"risk_level": 2,
"tools": ["nmap", "nuclei", "zap"],
"parameters": {
"ports": "80,443,8080",
"aggressive": false,
"follow_redirects": true
},
"schedule": null,
"notifications": {
"on_complete": ["slack", "email"],
"on_finding": ["slack"]
}
}
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Scan name (max 255 chars) |
target | string | Yes | Target URL, IP, or CIDR range |
scan_type | string | Yes | network, web, api, compliance, osint |
risk_level | integer | No | 0=SAFE, 1=NORMAL, 2=ELEVATED, 3=AGGRESSIVE (default: 1) |
tools | array | No | List of tools to execute |
parameters | object | No | Tool-specific parameters |
schedule | object | No | Scheduling configuration |
notifications | object | No | Notification preferences |
Response (201 Created):
{
"id": 124,
"name": "Web Application Security Assessment",
"target": "https://example.com",
"scan_type": "web",
"status": "pending",
"risk_level": 2,
"progress": 0,
"findings_count": 0,
"created_at": "2026-03-31T12:00:00Z",
"message": "Scan queued successfully",
"estimated_start": "2026-03-31T12:00:30Z"
}
Error Responses:
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_TARGET | Target validation failed (private IP, invalid URL) |
| 400 | INVALID_RISK_LEVEL | Risk level not available for user |
| 402 | SCAN_LIMIT_REACHED | Maximum concurrent scans exceeded |
| 429 | RATE_LIMIT_EXCEEDED | Too many scan requests |
Get Scan Details
Retrieve detailed information about a specific scan.
GET /api/v1/scans/{scan_id}
Authorization: Bearer {access_token}
Response (200 OK):
{
"id": 123,
"name": "Production Network Scan",
"target": "192.168.1.0/24",
"scan_type": "network",
"status": "completed",
"risk_level": 2,
"progress": 100,
"findings_count": 15,
"findings_summary": {
"critical": 2,
"high": 5,
"medium": 6,
"low": 2,
"info": 0
},
"tools_executed": [
{
"name": "nmap",
"status": "completed",
"started_at": "2026-03-31T10:05:00Z",
"completed_at": "2026-03-31T10:15:00Z",
"exit_code": 0
}
],
"created_at": "2026-03-31T10:00:00Z",
"started_at": "2026-03-31T10:05:00Z",
"completed_at": "2026-03-31T10:30:00Z",
"duration_seconds": 1500,
"logs": [
{
"timestamp": "2026-03-31T10:05:00Z",
"level": "info",
"message": "Starting Nmap scan"
}
]
}
Cancel Scan
Cancel a running or pending scan.
POST /api/v1/scans/{scan_id}/cancel
Authorization: Bearer {access_token}
Response (200 OK):
{
"id": 123,
"status": "cancelled",
"message": "Scan cancellation requested",
"cancelled_at": "2026-03-31T10:20:00Z"
}
Delete Scan
Delete a scan and all associated data.
DELETE /api/v1/scans/{scan_id}
Authorization: Bearer {access_token}
Response (204 No Content)
Get Scan Findings
Retrieve vulnerabilities found during a scan.
GET /api/v1/scans/{scan_id}/findings?severity=high,critical&tool=nuclei
Authorization: Bearer {access_token}
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
severity | string | Filter by severity: critical, high, medium, low, info |
tool | string | Filter by source tool |
confirmed | boolean | Filter by exploit confirmation status |
false_positive | boolean | Include/exclude false positives |
Response (200 OK):
{
"total": 15,
"data": [
{
"id": 456,
"scan_id": 123,
"title": "SQL Injection in Login Form",
"description": "User input is not properly sanitized before being used in SQL queries.",
"severity": "critical",
"cvss_score": 9.8,
"cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"cwe_id": "CWE-89",
"cve_id": null,
"tool": "sqlmap",
"target": "https://example.com/login",
"evidence": {
"request": "POST /login HTTP/1.1...",
"response": "SQL error: You have an error in your SQL syntax...",
"screenshot": "https://storage.../finding_456.png"
},
"exploit_available": true,
"exploit_confirmed": true,
"remediation": "Use parameterized queries or prepared statements. Validate all user input.",
"references": [
"https://owasp.org/www-community/attacks/SQL_Injection"
],
"created_at": "2026-03-31T10:10:00Z",
"status": "open"
}
]
}
Export Scan Report
Generate and download a scan report.
GET /api/v1/scans/{scan_id}/export?format=pdf&template=executive
Authorization: Bearer {access_token}
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
format | string | pdf | pdf, html, json, xml, sarif |
template | string | full | executive, technical, full, compliance |
include_evidence | boolean | true | Include screenshots and raw data |
include_false_positives | boolean | false | Include false positive findings |
Response (200 OK):
- Content-Type:
application/pdf(or appropriate format) - Content-Disposition:
attachment; filename="scan_123_report.pdf"
Tools
List Available Tools
Get all available security tools.
GET /api/v1/tools
Authorization: Bearer {access_token}
Response (200 OK):
{
"total": 72,
"categories": {
"reconnaissance": 15,
"scanning": 20,
"exploitation": 12,
"post_exploitation": 8,
"reporting": 5,
"utilities": 12
},
"data": [
{
"name": "nmap",
"display_name": "Nmap",
"version": "7.95",
"category": "scanning",
"description": "Network discovery and security auditing",
"risk_level": 1,
"parameters": [
{
"name": "ports",
"type": "string",
"required": false,
"default": "1-65535",
"description": "Port range to scan"
},
{
"name": "aggressive",
"type": "boolean",
"required": false,
"default": false,
"description": "Enable aggressive scan options"
}
],
"installed": true,
"supported_platforms": ["linux", "macos"]
}
]
}
Execute Tool
Execute a security tool directly.
POST /api/v1/tools/execute
Authorization: Bearer {access_token}
Content-Type: application/json
{
"tool_name": "nmap",
"target": "scanme.nmap.org",
"parameters": {
"ports": "22,80,443",
"service_detection": true,
"os_detection": false
},
"risk_level": 1,
"timeout": 300
}
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
tool_name | string | Yes | Name of the tool to execute |
target | string | Yes | Target for the tool |
parameters | object | No | Tool-specific parameters |
risk_level | integer | No | Override default risk level |
timeout | integer | No | Execution timeout in seconds (default: 300) |
Response (202 Accepted):
{
"execution_id": "exec_789",
"tool_name": "nmap",
"status": "queued",
"queued_at": "2026-03-31T12:00:00Z",
"estimated_start": "2026-03-31T12:00:05Z",
"position_in_queue": 3
}
Get Tool Execution Status
Check the status of a tool execution.
GET /api/v1/tools/execute/{execution_id}
Authorization: Bearer {access_token}
Response (200 OK):
{
"execution_id": "exec_789",
"tool_name": "nmap",
"status": "completed",
"target": "scanme.nmap.org",
"started_at": "2026-03-31T12:00:05Z",
"completed_at": "2026-03-31T12:02:30Z",
"duration_seconds": 145,
"exit_code": 0,
"stdout": "Starting Nmap 7.95...",
"stderr": "",
"output_format": "xml",
"parsed_output": {
"hosts": [
{
"ip": "45.33.32.156",
"hostname": "scanme.nmap.org",
"ports": [
{
"port": 22,
"protocol": "tcp",
"state": "open",
"service": "ssh",
"version": "OpenSSH 6.6.1"
}
]
}
]
},
"findings_generated": 3
}
Agents
List Agents
Get all AI agents and their status.
GET /api/v1/agents?status=active
Authorization: Bearer {access_token}
Response (200 OK):
{
"total": 6,
"active": 4,
"data": [
{
"id": "agent_001",
"name": "Network Security Expert",
"type": "specialist",
"status": "idle",
"persona": "network_expert",
"current_task": null,
"tasks_completed": 45,
"success_rate": 0.94,
"created_at": "2026-03-01T00:00:00Z",
"last_active": "2026-03-31T11:00:00Z",
"capabilities": ["nmap", "masscan", "zmap"]
}
]
}
Create Agent
Spawn a new AI agent.
POST /api/v1/agents
Authorization: Bearer {access_token}
Content-Type: application/json
{
"name": "Custom Web Agent",
"persona": "web_specialist",
"capabilities": ["nuclei", "zap", "ffuf"],
"max_concurrent_tasks": 5
}
Response (201 Created):
{
"id": "agent_007",
"name": "Custom Web Agent",
"status": "initializing",
"api_key": "zen_agent_xxx...",
"websocket_url": "ws://localhost:8000/ws/agents/agent_007"
}
Agent Action
Send an action to an agent.
POST /api/v1/agents/{agent_id}/action
Authorization: Bearer {access_token}
Content-Type: application/json
{
"action": "execute_scan",
"payload": {
"target": "example.com",
"tools": ["nuclei"]
}
}
Schedules
List Schedules
Get all scheduled scans.
GET /api/v1/schedules
Authorization: Bearer {access_token}
Response (200 OK):
{
"total": 5,
"data": [
{
"id": 10,
"name": "Weekly Network Scan",
"scan_template": {
"target": "10.0.0.0/24",
"scan_type": "network",
"tools": ["nmap"]
},
"cron_expression": "0 2 * * 0",
"timezone": "UTC",
"enabled": true,
"next_run": "2026-04-06T02:00:00Z",
"last_run": "2026-03-30T02:00:00Z",
"run_count": 12,
"created_at": "2026-01-01T00:00:00Z"
}
]
}
Create Schedule
Create a new scheduled scan.
POST /api/v1/schedules
Authorization: Bearer {access_token}
Content-Type: application/json
{
"name": "Daily Web Scan",
"scan_template": {
"target": "https://example.com",
"scan_type": "web",
"tools": ["nuclei", "zap"],
"risk_level": 1
},
"cron_expression": "0 3 * * *",
"timezone": "Europe/Berlin",
"enabled": true,
"notifications": {
"on_complete": ["email"]
}
}
Response (201 Created):
{
"id": 11,
"name": "Daily Web Scan",
"cron_expression": "0 3 * * *",
"next_run": "2026-04-01T03:00:00Z",
"enabled": true
}
Notifications
List Notification Channels
Get configured notification channels.
GET /api/v1/notifications/channels
Authorization: Bearer {access_token}
Response (200 OK):
{
"channels": [
{
"id": "slack_001",
"type": "slack",
"name": "Security Team",
"configured": true,
"test_status": "success"
},
{
"id": "email_001",
"type": "email",
"name": "Admin Email",
"configured": true,
"test_status": "success"
}
]
}
Test Notification
Send a test notification.
POST /api/v1/notifications/test
Authorization: Bearer {access_token}
Content-Type: application/json
{
"channel_id": "slack_001",
"message": "Test notification from Zen-AI-Pentest"
}
Reports
List Reports
Get all generated reports.
GET /api/v1/reports?scan_id=123
Authorization: Bearer {access_token}
Response (200 OK):
{
"total": 3,
"data": [
{
"id": "rep_456",
"scan_id": 123,
"format": "pdf",
"template": "executive",
"status": "ready",
"size_bytes": 2048576,
"created_at": "2026-03-31T12:00:00Z",
"download_url": "/api/v1/reports/rep_456/download"
}
]
}
Generate Report
Generate a new report.
POST /api/v1/reports
Authorization: Bearer {access_token}
Content-Type: application/json
{
"scan_id": 123,
"format": "pdf",
"template": "full",
"include_evidence": true
}
Response (202 Accepted):
{
"id": "rep_789",
"status": "generating",
"estimated_completion": "2026-03-31T12:05:00Z"
}
WebSocket
Real-time Updates
Connect to WebSocket for real-time scan updates.
const ws = new WebSocket('ws://localhost:8000/ws/scans');
ws.onopen = () => {
// Authenticate
ws.send(JSON.stringify({
type: 'auth',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6...'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'scan_update':
console.log(`Scan ${message.scan_id}: ${message.progress}%`);
break;
case 'finding':
console.log(`New finding: ${message.finding.title}`);
break;
case 'agent_status':
console.log(`Agent ${message.agent_id}: ${message.status}`);
break;
}
};
Message Types:
| Type | Description |
|---|---|
scan_update | Progress update for a scan |
finding | New vulnerability discovered |
agent_status | Agent status change |
tool_output | Live tool output stream |
notification | System notification |
error | Error notification |
Error Handling
Error Response Format
All errors follow a consistent format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request validation failed",
"details": [
{
"field": "target",
"message": "Invalid URL format"
}
],
"request_id": "req_abc123",
"timestamp": "2026-03-31T12:00:00Z"
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
AUTHENTICATION_REQUIRED | 401 | Missing or invalid authentication |
INVALID_TOKEN | 401 | JWT token is invalid or expired |
INSUFFICIENT_PERMISSIONS | 403 | User lacks required permissions |
RESOURCE_NOT_FOUND | 404 | Requested resource does not exist |
VALIDATION_ERROR | 422 | Request validation failed |
RATE_LIMIT_EXCEEDED | 429 | Too many requests |
TARGET_BLOCKED | 400 | Target is in blocklist (private IP, etc.) |
TOOL_NOT_AVAILABLE | 400 | Requested tool is not installed |
SCAN_LIMIT_REACHED | 402 | Maximum concurrent scans exceeded |
INTERNAL_ERROR | 500 | Server internal error |
Rate Limiting
Limits by Endpoint Category
| Category | Requests | Window |
|---|---|---|
| Authentication | 5 | 1 minute |
| Scans (create) | 10 | 1 minute |
| Tools (execute) | 20 | 1 minute |
| General API | 100 | 1 minute |
| Export/Download | 5 | 1 minute |
Rate Limit Headers
All responses include rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1711881600
X-RateLimit-Policy: 100;w=60
Retry-After: 60 # Only on 429 responses
OpenAPI Specification
Download OpenAPI JSON
curl http://localhost:8000/openapi.json > openapi.json
Generate Client SDKs
# Using OpenAPI Generator
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
-i /local/openapi.json \
-g python \
-o /local/zen_client
# Or for TypeScript
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
-i /local/openapi.json \
-g typescript-fetch \
-o /local/zen_client_ts
SDK Examples
Python
import requests
class ZenClient:
def __init__(self, base_url: str, token: str):
self.base_url = base_url
self.headers = {"Authorization": f"Bearer {token}"}
def create_scan(self, name: str, target: str, scan_type: str = "network"):
response = requests.post(
f"{self.base_url}/api/v1/scans",
headers=self.headers,
json={"name": name, "target": target, "scan_type": scan_type},
)
response.raise_for_status()
return response.json()
# Usage
client = ZenClient("http://localhost:8000", "your_token")
scan = client.create_scan("Network Test", "scanme.nmap.org")
print(f"Scan created: {scan['id']}")
JavaScript/TypeScript
class ZenClient {
constructor(private baseUrl: string, private token: string) {}
async createScan(name: string, target: string, scanType = "network") {
const response = await fetch(`${this.baseUrl}/api/v1/scans`, {
method: "POST",
headers: {
"Authorization": `Bearer ${this.token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ name, target, scan_type: scanType })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
}
// Usage
const client = new ZenClient("http://localhost:8000", "your_token");
const scan = await client.createScan("Network Test", "scanme.nmap.org");
console.log(`Scan created: ${scan.id}`);
cURL Examples
# Complete workflow example
# 1. Login
TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/login \
-d "username=admin&password=admin" \
| jq -r '.access_token')
# 2. Create scan
SCAN_ID=$(curl -s -X POST http://localhost:8000/api/v1/scans \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Test","target":"scanme.nmap.org","scan_type":"network"}' \
| jq -r '.id')
# 3. Wait for completion
while true; do
STATUS=$(curl -s http://localhost:8000/api/v1/scans/$SCAN_ID \
-H "Authorization: Bearer $TOKEN" \
| jq -r '.status')
echo "Status: $STATUS"
[ "$STATUS" = "completed" ] && break
sleep 5
done
# 4. Export report
curl -o report.pdf http://localhost:8000/api/v1/scans/$SCAN_ID/export?format=pdf \
-H "Authorization: Bearer $TOKEN"
echo "Report downloaded: report.pdf"
Changelog
v3.0.0 (2026-03-31)
- Initial API v3.0 release
- Added
/api/v1/prefix to all endpoints - Added WebSocket real-time updates
- Added bulk operations
- Improved error handling with request IDs
v2.3.0 (2025-07-01)
- Added schedule management endpoints
- Added notification channel configuration
- Added report generation API
v2.0.0 (2025-04-01)
- Initial stable API release
- JWT authentication
- Core scan management
Support
- 📖 Documentation: https://docs.zen-pentest.local
- 🐛 Issues: https://github.com/SHAdd0WTAka/Zen-Ai-Pentest/issues
- 💬 Discord: https://discord.gg/BSmCqjhY