Skip to main content
surfbot.

Authentication

How to authenticate with the Surfbot API using cookies, API keys, or Bearer tokens.

Base URL

All API requests are made to:

https://api.surfbot.io/api/v1

Auth endpoints (login, register, API key management) use:

https://api.surfbot.io/auth

Authentication Methods

The API supports three authentication methods, checked in this order:

When you log in via the web dashboard, the API sets an sb_token HttpOnly cookie automatically. This is the primary auth method for browser-based access.

# Login sets the cookie automatically
curl -X POST https://api.surfbot.io/auth/login \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{"email": "[email protected]", "password": "your-password"}'
 
# Subsequent requests use the cookie
curl -b cookies.txt https://api.surfbot.io/api/v1/domains

2. API Key Header (Integrations)

For programmatic access, use the X-API-Key header. Generate API keys from the dashboard or via the API.

curl -H "X-API-Key: sb_live_abc123def456" \
  https://api.surfbot.io/api/v1/domains

3. Bearer Token (Alternative)

You can also pass a JWT token in the Authorization header.

curl -H "Authorization: Bearer eyJhbGciOi..." \
  https://api.surfbot.io/api/v1/domains

API Key Management

Create API Key

POST /auth/api-keys

Requires authentication. Returns the full key only once — store it securely.

Request Body:

{
  "name": "CI/CD Pipeline",
  "scopes": ["read", "write"],
  "live": true
}
FieldTypeRequiredDescription
namestringYesA label for this key
scopesstring[]NoPermission scopes (default: [])
livebooleanNotrue for live key (sb_live_), false for test key (sb_test_)

Response (201):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "CI/CD Pipeline",
  "prefix": "sb_live_abc1",
  "scopes": ["read", "write"],
  "created_at": "2026-03-15T10:00:00Z",
  "key": "sb_live_abc123def456ghi789..."
}

Important: The key field is only returned on creation. Store it immediately.

List API Keys

GET /auth/api-keys

Returns all API keys for your organization. Keys are shown with prefix only (not the full key).

curl -H "X-API-Key: sb_live_abc123def456" \
  https://api.surfbot.io/auth/api-keys

Response (200):

{
  "api_keys": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "CI/CD Pipeline",
      "prefix": "sb_live_abc1",
      "scopes": ["read", "write"],
      "created_at": "2026-03-15T10:00:00Z"
    }
  ],
  "count": 1
}

Revoke API Key

DELETE /auth/api-keys/:id
curl -X DELETE \
  -H "X-API-Key: sb_live_abc123def456" \
  https://api.surfbot.io/auth/api-keys/550e8400-e29b-41d4-a716-446655440000

Response (200):

{
  "message": "api key revoked"
}

Error Format

Error responses use this format:

{
  "error": "unauthorized",
  "message": "authentication required"
}

Some errors include additional fields:

{
  "error": "invalid request",
  "details": "Key: 'Email' Error:Field validation for 'Email' failed"
}

Rate Limits

Rate limits are applied per IP and per user, independent of your plan tier.

ScopeLimit
Unauthenticated100 req/min per IP
Authenticated1,000 req/min per IP
Per user300 req/min per user
Auth endpoints (login, register)10 req/min per IP
OAuth callbacks20 req/min per IP
Registration3 per IP per 24h

Rate limit headers are included in every response:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997

When rate limited, you receive a 429 response with a Retry-After header:

{
  "error": "rate_limit_exceeded",
  "message": "too many requests",
  "retry_after": 45
}

HTTP Status Codes

CodeMeaning
200Success
201Created
202Accepted (scan queued)
400Bad request — check your parameters
401Unauthorized — invalid or missing credentials
403Forbidden — insufficient permissions or quota exceeded
404Resource not found
409Conflict — resource already exists
422Unprocessable entity — validation failed
429Rate limited — retry after the indicated time
500Internal server error
503Service unavailable — rate limiting service down

On this page