API Reference
REST API Reference

REST API Reference

The NAT server exposes a REST API that lets you start scans, retrieve results, and manage your workspace programmatically. This is the same API used by the NAT CLI and dashboard.

The REST API is available in both the SaaS hosted version (base URL: https://api.nat-testing.io/v1) and the self-hosted server (base URL: http://localhost:8080/api/v1).

Authentication

All API endpoints require authentication using an API key:

Authorization: Bearer YOUR_API_KEY

Generate an API key from the dashboard under Settings → API Keys.

Base URL

DeploymentBase URL
SaaShttps://api.nat-testing.io/v1
Self-hostedhttp://YOUR_HOST:PORT/api/v1

Scans

Start a scan

POST /scans

Request body:

{
  "url": "https://api.example.com",
  "spec_url": "https://api.example.com/openapi.json",
  "auth": {
    "type": "bearer",
    "token": "eyJ..."
  },
  "options": {
    "concurrency": 5,
    "timeout": 30,
    "fail_on": "high",
    "exclude": ["/api/v1/payments/*"]
  }
}

Request fields:

FieldTypeRequiredDescription
urlstringTarget API base URL
spec_urlstringOpenAPI/Swagger spec URL
spec_contentstringBase64-encoded spec content (alternative to spec_url)
auth.typestringbearer, header, basic, oauth2, none
auth.tokenstringBearer token value
auth.header_namestringHeader name for header auth type
auth.header_valuestringHeader value for header auth type
auth.usernamestringUsername for basic auth
auth.passwordstringPassword for basic auth
auth.oauth2_token_urlstringOAuth2 token endpoint
auth.oauth2_client_idstringOAuth2 client ID
auth.oauth2_client_secretstringOAuth2 client secret
auth.oauth2_scopestringOAuth2 scopes
options.concurrencyintegerParallel request count (default: 5)
options.timeoutintegerPer-request timeout seconds (default: 30)
options.fail_onstringSeverity level for non-zero exit: critical, high, medium, low
options.excludestring[]Path patterns to exclude from scanning

Response 201 Created:

{
  "scan_id": "scan_abc123xyz",
  "status": "queued",
  "created_at": "2025-01-15T10:30:00Z",
  "estimated_duration_seconds": 120
}

Get scan status

GET /scans/{scan_id}

Response 200 OK:

{
  "scan_id": "scan_abc123xyz",
  "status": "running",
  "progress": {
    "endpoints_discovered": 42,
    "endpoints_tested": 18,
    "findings": 3
  },
  "created_at": "2025-01-15T10:30:00Z",
  "started_at": "2025-01-15T10:30:05Z",
  "completed_at": null
}

Status values: queued, running, complete, failed


List scans

GET /scans

Query parameters:

ParameterDescriptionDefault
pagePage number1
per_pageResults per page (max 100)20
statusFilter by statusAll

Response 200 OK:

{
  "scans": [...],
  "total": 47,
  "page": 1,
  "per_page": 20
}

Cancel a scan

DELETE /scans/{scan_id}

Response 204 No Content


Findings

Get findings for a scan

GET /scans/{scan_id}/findings

Query parameters:

ParameterDescription
severityFilter: critical, high, medium, low, info
statusFilter: open, resolved, accepted
pagePage number
per_pageResults per page

Response 200 OK:

{
  "findings": [
    {
      "id": "find_001",
      "severity": "high",
      "title": "Broken Object Level Authorization",
      "owasp": "API1",
      "cwe": "CWE-639",
      "endpoint": "GET /api/v1/users/{id}",
      "risk_score": 78,
      "status": "open",
      "evidence": {
        "request": "GET /api/v1/users/42 HTTP/1.1\nAuthorization: Bearer <user-b-token>",
        "response": "HTTP/1.1 200 OK\n{\"id\":42,\"email\":\"alice@example.com\",...}"
      },
      "remediation": "Verify that the authenticated user is authorized to access the requested resource ID before returning data."
    }
  ],
  "total": 3,
  "page": 1,
  "per_page": 20
}

Get scan report

GET /scans/{scan_id}/report

Query parameters:

ParameterDescriptionDefault
formathtml, json, sarif, markdownjson

Response: Report file with appropriate Content-Type.


Reports

Download a report

GET /reports/{scan_id}

Query parameters:

ParameterValues
formathtml, json, sarif

Errors

All errors follow RFC 7807 (Problem Details):

{
  "type": "https://docs.nat-testing.io/errors/scan-not-found",
  "title": "Scan Not Found",
  "status": 404,
  "detail": "No scan found with ID scan_xyz123",
  "instance": "/scans/scan_xyz123"
}

Common error codes:

HTTP StatusMeaning
400 Bad RequestInvalid request body or parameters
401 UnauthorizedMissing or invalid API key
403 ForbiddenValid key but insufficient permissions
404 Not FoundRequested resource does not exist
409 ConflictDuplicate resource or conflicting state
429 Too Many RequestsRate limit exceeded
500 Internal Server ErrorServer error — contact support

Rate limits

PlanRequests per minute
Free60
Pro300
Enterprise1,000
Self-hostedUnlimited

Rate limit headers are included in all responses:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 295
X-RateLimit-Reset: 1705315800