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


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:

FieldTypeRequiredDescription
usernamestringYesUser login name
passwordstringYesUser password

Response (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}

Error Responses:

StatusCodeDescription
401INVALID_CREDENTIALSUsername or password incorrect
403ACCOUNT_LOCKEDAccount temporarily locked
429RATE_LIMIT_EXCEEDEDToo 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:

ParameterTypeDefaultDescription
skipinteger0Number of records to skip
limitinteger20Maximum records to return (max: 100)
statusstring-Filter by status: pending, running, completed, failed, cancelled
scan_typestring-Filter by type: network, web, api, compliance
targetstring-Filter by target (partial match)
created_afterdatetime-Filter by creation date (ISO 8601)
created_beforedatetime-Filter by creation date (ISO 8601)
sortstring-created_atSort 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:

FieldTypeRequiredDescription
namestringYesScan name (max 255 chars)
targetstringYesTarget URL, IP, or CIDR range
scan_typestringYesnetwork, web, api, compliance, osint
risk_levelintegerNo0=SAFE, 1=NORMAL, 2=ELEVATED, 3=AGGRESSIVE (default: 1)
toolsarrayNoList of tools to execute
parametersobjectNoTool-specific parameters
scheduleobjectNoScheduling configuration
notificationsobjectNoNotification 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:

StatusCodeDescription
400INVALID_TARGETTarget validation failed (private IP, invalid URL)
400INVALID_RISK_LEVELRisk level not available for user
402SCAN_LIMIT_REACHEDMaximum concurrent scans exceeded
429RATE_LIMIT_EXCEEDEDToo 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:

ParameterTypeDescription
severitystringFilter by severity: critical, high, medium, low, info
toolstringFilter by source tool
confirmedbooleanFilter by exploit confirmation status
false_positivebooleanInclude/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:

ParameterTypeDefaultDescription
formatstringpdfpdf, html, json, xml, sarif
templatestringfullexecutive, technical, full, compliance
include_evidencebooleantrueInclude screenshots and raw data
include_false_positivesbooleanfalseInclude 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:

FieldTypeRequiredDescription
tool_namestringYesName of the tool to execute
targetstringYesTarget for the tool
parametersobjectNoTool-specific parameters
risk_levelintegerNoOverride default risk level
timeoutintegerNoExecution 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:

TypeDescription
scan_updateProgress update for a scan
findingNew vulnerability discovered
agent_statusAgent status change
tool_outputLive tool output stream
notificationSystem notification
errorError 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

CodeHTTP StatusDescription
AUTHENTICATION_REQUIRED401Missing or invalid authentication
INVALID_TOKEN401JWT token is invalid or expired
INSUFFICIENT_PERMISSIONS403User lacks required permissions
RESOURCE_NOT_FOUND404Requested resource does not exist
VALIDATION_ERROR422Request validation failed
RATE_LIMIT_EXCEEDED429Too many requests
TARGET_BLOCKED400Target is in blocklist (private IP, etc.)
TOOL_NOT_AVAILABLE400Requested tool is not installed
SCAN_LIMIT_REACHED402Maximum concurrent scans exceeded
INTERNAL_ERROR500Server internal error

Rate Limiting

Limits by Endpoint Category

CategoryRequestsWindow
Authentication51 minute
Scans (create)101 minute
Tools (execute)201 minute
General API1001 minute
Export/Download51 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