Authentication

Authentication

All /v1/* endpoints require an API key. A handful of utility routes are public and require no authentication.

Public routes (no auth)

PathDescription
GET /healthHealth check, returns { ok: true, version: "…" }
GET /llms.txtCondensed API reference for AI agents
GET /llms-full.txtFull API reference for AI agents
GET /openapi.jsonOpenAPI 3.x spec

Public under /v1/ without a key: GET /v1/pricing, GET /v1/status, POST /v1/keys/provision. Everything else under /v1/ requires a valid API key.

Passing your API key

Use the x-api-key header. It is the canonical form and the one every example in these docs uses:

curl -H "x-api-key: ss_live_xxxxxxxxxxxxxxxxxxxx" 

Authorization: Bearer ss_live_… is also accepted and resolves to the same key, so an existing client that already sends a bearer token will work unchanged. When both headers are present, x-api-key wins. This is the only page that documents the bearer form; prefer x-api-key everywhere else.

Any request that omits both headers returns:

HTTP 401
{ "error": "API key required. Pass via x-api-key header." }

Key format

Keys follow the pattern ss_<token>. The prefix is for visual identification only, any string that resolves to an active row in the api_keys table is accepted. Keys are stored as SHA-256 hashes; the plaintext is only available at creation time.

Getting a key

Dashboard (normal flow)

  1. Sign in at app.superscraper.dev (opens in a new tab).
  2. Go to Settings → API Keys and click Create key.
  3. Copy the key immediately, it is shown only once.

Self-serve provisioning (agents / scripts)

POST /v1/keys/provision is public, it is mounted ahead of the auth guard, so it needs no existing key and no sign-in. It mints a fresh free-tier tenant and returns the plaintext key once:

curl -X POST https://api.superscraper.dev/v1/keys/provision \
  -H "Content-Type: application/json" \
  -d '{"label": "my-agent"}'
{
  "apiKey": "ss_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "tenantId": "8f3c…",
  "tier": "free"
}

Store apiKey immediately, it cannot be retrieved again. The route is IP rate-limited and issues free-tier keys only; to do paid work, fund credits from the dashboard.

Key lifecycle

StateBehaviour
ActiveAll /v1/* requests are allowed (subject to rate limits and tier quotas)
RevokedReturns HTTP 401 "Invalid or revoked API key." on every request

Keys can be revoked from the dashboard. Once revoked, they cannot be re-activated, create a new key instead.

Error responses

StatusJSONCause
401"API key required. Pass via x-api-key header."No key header present
401"Invalid or revoked API key."Key not found in database or is_active = false

Rate limits

Rate limits apply per key, per 60-second sliding window:

PlanRequests / minute
Free10
Hobby60
Pro200
Scale600
Custom3 000

Exceeding the limit returns HTTP 429 with a Retry-After: 60 header.

Security notes

  • Keys are never logged. The server stores only the SHA-256 hash.
  • All requests over plain HTTP are rejected (HTTPS only in production).
  • Each request updates last_used_at on the key row (fire-and-forget, non-blocking).
  • Treat keys like passwords: do not commit them to version control or expose them client-side. Use environment variables (SUPERSCRAPER_API_KEY) in your applications.