API Reference
The Guardr API lets you scan any website for security misconfigurations and read results programmatically — perfect for CI/CD pipelines, internal dashboards, and automated security checks.
Authentication
Authenticate by passing your API key in the X-API-Key request header.
Get your key from Dashboard → Settings → API Access.
X-API-Key: your_key_here
Base URL
https://api.guardr.io
Quickstart
Scan a domain and read the results in two steps.
1. Read a cached scan result (no key required)
curl https://api.guardr.io/v1/scan/example.com
2. Trigger a fresh scan and read the result (API key required)
curl -X POST https://api.guardr.io/v1/scan \
-H "X-API-Key: your_key_here" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}' Scanning multiple domains (loop pattern)
domains=("example.com" "another.io" "mysite.com")
for domain in "${domains[@]}"; do
curl -X POST https://api.guardr.io/v1/scan \
-H "X-API-Key: your_key_here" \
-H "Content-Type: application/json" \
-d "{\"domain\": \"$domain\"}"
done Quota is per-domain — scanning 10 different domains uses 10 quota slots, not 10× a single slot.
/v1/scan/:domain
Returns the most recent cached scan result for a domain. Never triggers a new scan — use POST /v1/scan for that.
Parameters
| Parameter | Type | Description |
|---|---|---|
| domain | path | Bare hostname, e.g. example.com |
Example request
curl https://api.guardr.io/v1/scan/example.com \ -H "X-API-Key: your_key_here"
Response — Solo+ (full results)
{
"domain": "example.com",
"scanned_at": "2026-04-18T10:00:00.000Z",
"grade": "C",
"score": 61,
"categories": {
"tls": 90,
"headers": 40,
"cookies": 100,
"dns": 80,
"exposure": 100
},
"issues": [
{
"title": "Missing: content-security-policy",
"severity": "high",
"category": "Security Headers",
"description": "...",
"remediation": {
"summary": "...",
"effort": "requires-planning",
"snippets": [...]
}
}
],
"issues_truncated": false,
"total_issues": 4,
"secrets_found": []
} Response — Free tier (truncated)
{
"domain": "example.com",
"grade": "C",
"score": 61,
"categories": { ... },
"issues_truncated": true,
"total_issues": 9,
"upgrade_url": "https://guardr.io/dashboard/billing"
} Free accounts see the top 3 critical/high severity issues with full remediation steps. Upgrade to Solo or higher for all results.
/v1/scan
Free+Triggers a fresh security scan for a domain. Runs inline and returns results in ~5–15 seconds. The result is cached for 1 hour and readable via GET /v1/scan/:domain.
Request body
| Field | Type | Description |
|---|---|---|
| domain * | string | Domain to scan, e.g. example.com |
Example request
curl -X POST https://api.guardr.io/v1/scan \
-H "X-API-Key: your_key_here" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}' /v1/account
Returns your current plan, quota configuration, and list of active API keys.
curl https://api.guardr.io/v1/account \ -H "X-API-Key: your_key_here"
{
"plan": "starter",
"quota": {
"scan_window": 86400,
"burst_per_minute": 30
},
"keys": [
{
"key_id": "...",
"display": "••••••••••••••••f630",
"label": "CI pipeline",
"created_at": "18.04.2026",
"last_used_at": "18.04.2026",
"revoked": false
}
]
} Rate limits
Two independent limits apply to every request: a per-minute burst limit and a per-domain scan quota.
| Plan | Burst limit | Scan quota | Quota window |
|---|---|---|---|
| Public (no key) | 20 req/day per IP | Read only | — |
| Free | 5 req/min | 1/domain | 7 days |
| Solo | 15 req/min | 1/domain | 24 hours |
| Starter | 30 req/min | 1/domain | 24 hours |
| Pro | 60 req/min | 1/domain | 6 hours |
| Agency | 120 req/min | 1/domain | 1 hour |
When a limit is exceeded, the API returns 429 Too Many Requests with these headers:
X-RateLimit-Limit: 60 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1713441600 Retry-After: 47
Error codes
All errors return JSON with an error field and a human-readable message.
| HTTP | error | Meaning |
|---|---|---|
| 400 | invalid_domain | Domain is malformed, private, or blocked |
| 400 | invalid_body | Request body is not valid JSON |
| 401 | invalid_key | Key not found or revoked |
| 401 | missing_key | Endpoint requires a key, none was provided |
| 404 | scan_not_found | No cached scan exists — use POST /v1/scan |
| 404 | not_found | Unknown API endpoint |
| 422 | scan_failed | Scanner could not reach the domain |
| 429 | rate_limit_exceeded | Per-minute burst limit hit |
| 429 | quota_exceeded | Per-domain scan quota hit for this window |
Plan comparison
| Plan | GET results | POST scan | Keys |
|---|---|---|---|
| Public | Grade + score only | — | — |
| Free | Top 3 issues | ✓ | 1 |
| Solo $7/mo | Full results | ✓ | 1 |
| Starter $19/mo | Full results | ✓ | 1 |
| Pro $69/mo | Full results | ✓ | 2 |
| Agency $179/mo | Full results | ✓ | 5 |
Migrating from SecurityHeaders.com
SecurityHeaders.com shut down its free API in April 2026. Here's how to migrate to Guardr.
Before (SecurityHeaders.com)
curl "https://api.securityheaders.com/?q=example.com&hide=on&followRedirects=on" \ -H "x-api-key: your_key"
After (Guardr)
curl -X POST https://api.guardr.io/v1/scan \
-H "X-API-Key: your_key_here" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}' What Guardr adds
| Feature | SecurityHeaders | Guardr |
|---|---|---|
| Security headers scan | ✓ | ✓ |
| A–F grade | ✓ | ✓ |
| Remediation instructions | — | ✓ |
| SSL/TLS + HSTS check | — | ✓ |
| DNS security (DNSSEC, CAA) | — | ✓ |
| Exposed file detection (.env, .git) | — | ✓ |
| JS bundle secret scanning | — | ✓ |
| Free tier | — | ✓ |