Authentication
The Surfinguard API uses API key authentication. Keys are passed in the Authorization header as Bearer tokens.
API Key Format
API keys follow a predictable format:
| Prefix | Environment | Example |
|---|---|---|
sg_live_ | Production | sg_live_a1b2c3d4e5f6g7h8i9j0 |
sg_test_ | Testing | sg_test_x9y8w7v6u5t4s3r2q1p0 |
Test keys have the same rate limits as live keys but are tagged separately for analytics. Both key types access the same API endpoints.
Making Authenticated Requests
Include the API key in the Authorization header:
curl -X POST https://api.surfinguard.com/v2/check/url \
-H "Authorization: Bearer sg_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'Unauthenticated Access
When AUTH_REQUIRED is set to false (the default for the public API), unauthenticated requests are allowed at Free tier rate limits. This is useful for evaluation and testing without obtaining an API key first.
# Works without an API key (Free tier limits apply)
curl -X POST https://api.surfinguard.com/v2/check/url \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'Rate Limits
Rate limits are enforced per API key (or per IP for unauthenticated requests):
| Tier | Requests/Minute | Requests/Day | Price |
|---|---|---|---|
| Free | 10 | 1,000 | Free |
| Developer | 60 | 50,000 | — |
| Business | 300 | 500,000 | — |
| Enterprise | 1,000 | 5,000,000 | — |
Rate Limit Headers
Every response includes rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1706745600
X-RateLimit-Daily-Limit: 50000
X-RateLimit-Daily-Remaining: 49997| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per minute |
X-RateLimit-Remaining | Remaining requests this minute |
X-RateLimit-Reset | Unix timestamp when the minute window resets |
X-RateLimit-Daily-Limit | Max requests per day |
X-RateLimit-Daily-Remaining | Remaining requests today |
Rate Limit Exceeded
When you exceed the rate limit, the API returns 429 Too Many Requests:
{
"error": "Rate limit exceeded",
"retryAfter": 42
}The Retry-After header indicates how many seconds to wait before retrying.
Key Management
Create a Key
curl -X POST https://api.surfinguard.com/v2/keys \
-H "Authorization: Bearer sg_live_admin_key" \
-H "Content-Type: application/json" \
-d '{"name": "production-agent", "tier": "developer"}'Response:
{
"id": "key_abc123",
"key": "sg_live_newly_generated_key",
"name": "production-agent",
"tier": "developer",
"created_at": "2026-01-15T10:30:00Z"
}The full key is only returned once at creation time. Store it securely.
List Keys
curl https://api.surfinguard.com/v2/keys \
-H "Authorization: Bearer sg_live_admin_key"Revoke a Key
curl -X DELETE https://api.surfinguard.com/v2/keys/key_abc123 \
-H "Authorization: Bearer sg_live_admin_key"View Key Usage
curl https://api.surfinguard.com/v2/keys/key_abc123/usage \
-H "Authorization: Bearer sg_live_admin_key"Response:
{
"key_id": "key_abc123",
"today": {
"total": 1247,
"by_type": {
"url": 892,
"command": 203,
"text": 152
}
}
}Security Best Practices
- Never commit API keys to version control. Use environment variables or secret managers.
- Use test keys during development:
sg_test_keys have the same behavior but are tracked separately. - Rotate keys regularly and revoke any compromised keys immediately.
- Use the minimum tier needed. Start with Free and upgrade as your usage grows.
- Scope keys by environment: Use separate keys for development, staging, and production.