Authentication

The SEOLadders API uses bearer-token authentication. Every request includes an API key in the Authorization header.

API key format

Keys look like sk_live_ followed by a 48-character hex secret. Each key works across every site on your account — pick which site each request runs against per call (see Multi-site).

Legacy keys (single-site)

Keys minted before the multi-site release are locked to one site and ignore the X-Site override. They keep working unchanged. The Developers page labels them “Single site” vs new “All sites” keys.

Multi-site — picking which site this runs against

When your account has more than one site, pass the site you want to target on each request via either:

  • X-Site: acme.com header (recommended)
  • ?site=acme.com query string parameter (handy for curl one-liners — if both are set, the header wins)
bash
curl https://www.seoladders.com/api/v1/keywords/search \
  -H "Authorization: Bearer sk_live_••••••••••••••••" \
  -H "X-Site: acme.com" \
  -H "Content-Type: application/json" \
  -d '{"seed": "best crm for startups"}'

The site value is the canonical hostname — we normalize on lookup so https://www.acme.com/ and acme.com resolve the same way. Omit both and the request runs against your active site — whichever one you last switched to in the dashboard sidebar. A bad hostname returns 404 not_found with the normalized value we tried to match.

Creating keys

Generate keys on the Developers page:

  1. Sign in to the dashboard and open /dashboard/developers
  2. Click Create API key and give it a label (e.g., “CI/CD”, “Local dev”)
  3. Copy the key immediately — we show the secret only once
  4. Store it in a secrets manager or environment variable (never in source)

One-time display

We hash keys at rest and only show the plaintext once. If you lose a key, rotate it — there's no way to retrieve the original.

Rotation

Keys can be rotated at any time without downtime. Issue a new key, deploy it to your environment, then revoke the old one. The dashboard shows last-used timestamps so you can confirm a key is no longer in use before revoking.

  • Rotate proactively on a 90-day cadence for production keys
  • Rotate immediately if a key was logged, leaked, or committed to source control
  • Use separate keys per environment (dev, staging, production) so blast radius is bounded

Storing keys

Recommended patterns by environment:

.env.local
# .env.local
SEOLADDERS_API_KEY=sk_live_••••••••••••••••
SEOLADDERS_API_BASE=https://www.seoladders.com/api/v1
  • Local development .env.local with .gitignore entry
  • Vercel / Netlify — project environment variables, marked encrypted
  • Cloud providers — AWS Secrets Manager, GCP Secret Manager, Azure Key Vault
  • Self-hosted — Doppler, HashiCorp Vault, 1Password CLI

Browser usage

Don't expose API keys in client-side code. Proxy through your backend or a serverless function so the key stays server-side.

MCP authentication

The MCP server uses the same API keys. When you set up the MCP server in Claude Code, Cursor, or another client, you'll provide the API key in the server's environment or configuration. The MCP server adds the bearer header automatically on every tool call. See MCP Setup for the full configuration.

Webhook signing

Webhooks use a separate signing secret (HMAC-SHA256), distinct from API keys. Each product has one webhook signing secret you can rotate on the Developers page. See Webhooks for verification examples.

Quota & rate limits

Each surface (article generation, keyword research, optimization, and so on) has a per-month quota tied to your subscription tier. When a surface's quota is exhausted, calls to it return 429 Too Many Requests with a rate_limited error:

json
{
  "error": "rate_limited",
  "message": "Monthly quota reached for this surface. Upgrade your plan or wait for the reset."
}

Track remaining quota per surface on the Usage & billing page in the dashboard.