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_KEYGenerate an API key from the dashboard under Settings → API Keys.
Base URL
| Deployment | Base URL |
|---|---|
| SaaS | https://api.nat-testing.io/v1 |
| Self-hosted | http://YOUR_HOST:PORT/api/v1 |
Scans
Start a scan
POST /scansRequest 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:
| Field | Type | Required | Description |
|---|---|---|---|
url | string | ✅ | Target API base URL |
spec_url | string | OpenAPI/Swagger spec URL | |
spec_content | string | Base64-encoded spec content (alternative to spec_url) | |
auth.type | string | bearer, header, basic, oauth2, none | |
auth.token | string | Bearer token value | |
auth.header_name | string | Header name for header auth type | |
auth.header_value | string | Header value for header auth type | |
auth.username | string | Username for basic auth | |
auth.password | string | Password for basic auth | |
auth.oauth2_token_url | string | OAuth2 token endpoint | |
auth.oauth2_client_id | string | OAuth2 client ID | |
auth.oauth2_client_secret | string | OAuth2 client secret | |
auth.oauth2_scope | string | OAuth2 scopes | |
options.concurrency | integer | Parallel request count (default: 5) | |
options.timeout | integer | Per-request timeout seconds (default: 30) | |
options.fail_on | string | Severity level for non-zero exit: critical, high, medium, low | |
options.exclude | string[] | 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 /scansQuery parameters:
| Parameter | Description | Default |
|---|---|---|
page | Page number | 1 |
per_page | Results per page (max 100) | 20 |
status | Filter by status | All |
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}/findingsQuery parameters:
| Parameter | Description |
|---|---|
severity | Filter: critical, high, medium, low, info |
status | Filter: open, resolved, accepted |
page | Page number |
per_page | Results 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}/reportQuery parameters:
| Parameter | Description | Default |
|---|---|---|
format | html, json, sarif, markdown | json |
Response: Report file with appropriate Content-Type.
Reports
Download a report
GET /reports/{scan_id}Query parameters:
| Parameter | Values |
|---|---|
format | html, 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 Status | Meaning |
|---|---|
400 Bad Request | Invalid request body or parameters |
401 Unauthorized | Missing or invalid API key |
403 Forbidden | Valid key but insufficient permissions |
404 Not Found | Requested resource does not exist |
409 Conflict | Duplicate resource or conflicting state |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | Server error — contact support |
Rate limits
| Plan | Requests per minute |
|---|---|
| Free | 60 |
| Pro | 300 |
| Enterprise | 1,000 |
| Self-hosted | Unlimited |
Rate limit headers are included in all responses:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 295
X-RateLimit-Reset: 1705315800