POST
/v1/scan Create Scan.
Submit a URL for scanning. The scan runs asynchronously — poll GET /v1/scan/:id for status updates.
Authentication
Requires a valid API key via Authorization: Bearer header.
Each scan counts toward your monthly quota.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The target URL to scan. Must be a valid https:// or http:// URL with a resolvable hostname. |
type | string | Yes | Scan type: security, performance, accessibility, or seo. |
callback_url | string | No | Webhook URL to receive a POST when the scan completes. Must be HTTPS. |
Response
Returns 201 Created on success:
{
"id": "scan_abc123",
"status": "queued",
"type": "security",
"url": "https://example.com",
"created_at": "2026-03-30T12:00:00Z"
} | Field | Type | Description |
|---|---|---|
id | string | Unique scan identifier. Use this to poll status and retrieve the report. |
status | string | Always "queued" on creation. |
type | string | The scan type you requested. |
url | string | The normalized target URL. |
created_at | string | ISO 8601 timestamp in UTC. |
Error responses
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_URL | The URL is malformed or uses an unsupported protocol. |
| 400 | INVALID_TYPE | The scan type is not one of the four valid types. |
| 400 | URL_NOT_REACHABLE | The target URL did not respond or returned a DNS error. |
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 403 | DOMAIN_BLOCKED | The target domain is on the blocklist (e.g., localhost, internal IPs). |
| 429 | RATE_LIMITED | Too many requests. Retry after the X-RateLimit-Reset timestamp. |
| 429 | QUOTA_EXCEEDED | Monthly scan quota exhausted. Upgrade your plan or wait for the next cycle. |
Code examples
cURL
curl -X POST https://appvet.dev/v1/scan \
-H "Authorization: Bearer avk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"type": "security"
}' Python
import requests
resp = requests.post(
"https://appvet.dev/v1/scan",
headers={"Authorization": "Bearer avk_live_your_key_here"},
json={"url": "https://example.com", "type": "security"},
)
scan = resp.json()
print(f"Scan ID: {scan['id']}, Status: {scan['status']}") Node.js
const resp = await fetch("https://appvet.dev/v1/scan", {
method: "POST",
headers: {
Authorization: "Bearer avk_live_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com",
type: "security",
}),
});
const scan = await resp.json();
console.log(`Scan ID: ${scan.id}, Status: ${scan.status}`);