REST API
Build custom integrations with ScanAtlas
Authentication
All API requests require authentication using an API key. Include your key in the Authorization header:
Authorization: Bearer sa_live_your_api_key_hereGenerate your API key in Settings → API. API access requires a Starter or Pro plan.
Rate Limits
General API
60 requests/minute
Scan Creation
10 requests/minute
Rate limit headers are included in all responses:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1704067200Quick Start
Create a scan
curl -X POST "https://scanatlas.com/api/v1/scans" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'List your scans
curl "https://scanatlas.com/api/v1/scans?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"Get scan details
curl "https://scanatlas.com/api/v1/scans/SCAN_ID" \
-H "Authorization: Bearer YOUR_API_KEY"Endpoints Reference
/api/v1/scansCreate a new scan
Request Body:
{ "url": "https://example.com" }Response:
{
"data": {
"id": "uuid",
"siteUrl": "https://example.com",
"status": "queued",
"createdAt": "2024-01-01T00:00:00.000Z"
},
"usage": {
"scansUsed": 1,
"scansLimit": 10,
"scansRemaining": 9
}
}/api/v1/scansList your scans
Query Parameters:
- limit (default: 20, max: 100)
- offset (default: 0)
- status (filter)
Response:
{
"data": [...],
"pagination": { "limit": 20, "offset": 0, "hasMore": true }
}/api/v1/scans/:idGet scan details
Response:
{
"data": {
"id": "uuid",
"siteUrl": "https://example.com",
"status": "completed",
"healthScore": 85,
"totalPages": 10,
"errorCount": 2,
"warningCount": 5
}
}/api/v1/scans/:id/pagesGet pages for a scan
Response:
{
"data": [
{ "url": "/", "statusCode": 200, "loadTime": 1234 },
...
]
}/api/v1/scans/:id/issuesGet issues for a scan
Query Parameters:
- severity (error, warning, info)
- category
Response:
{
"data": [
{
"severity": "error",
"category": "seo",
"message": "Missing meta description",
"pageUrl": "/"
},
...
]
}/api/v1/scans/:id/reportGet a text report optimized for LLMs
Response:
{ "data": { "content": "..." } }Error Codes
| Code | Description |
|---|---|
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - API access requires paid plan |
| 404 | Not Found - Resource doesn't exist |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
Common Workflows
Scan and Wait for Completion
// 1. Start a scan
const { data: scan } = await fetch('/api/v1/scans', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://example.com' })
}).then(r => r.json());
// 2. Poll for completion
let status = scan.status;
while (status !== 'completed' && status !== 'failed') {
await new Promise(r => setTimeout(r, 5000)); // Wait 5 seconds
const { data } = await fetch(`/api/v1/scans/${scan.id}`, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
status = data.status;
}
// 3. Get results
const results = await fetch(`/api/v1/scans/${scan.id}/issues`, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());Get LLM-Friendly Report
The /report endpoint returns a text report optimized for AI assistants.
const { data } = await fetch('/api/v1/scans/SCAN_ID/report', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
// data.content contains a formatted text report suitable for LLMsPrefer AI Integration?
For direct integration with Claude, Cursor, or other AI assistants, check out our MCP Server for natural language website scanning.