extractr docs

Authentication

Authenticate every data request with an API key.

All data endpoints require an API key. Create and manage keys in the dashboard.

Sending your key

Two equivalent options — pick one:

curl "https://api.extractr.dev/ra/search?q=berlin" \
  -H "X-API-Key: ext_live_YOUR_KEY"

Key format

Secret keys look like:

ext_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
  • The ext_live_ prefix is followed by 40 hex characters.
  • The full secret is returned exactly once, when the key is created. Only a display prefix (e.g. ext_live_a1b2) is stored — if you lose the secret, create a new key.

Revoking and rotating

Revoke a key any time from the dashboard; it stops working immediately. To rotate without downtime:

  1. Create a new key.
  2. Deploy the new key to your services.
  3. Revoke the old key.

Billing is per account rather than per key, so you can freely create one key per service or environment.

Keep keys server-side

Never ship an API key in client-side code. Anyone with the key can spend your credits. Proxy extractr calls through your backend.

Key scopes

By default a key can call every provider, including ones added after it was created. You can instead restrict a key to named providers — useful when a key goes somewhere you control less tightly, such as an AI agent over MCP or a service that only needs one data source.

Set scopes when creating a key, or edit them later from API Keys → Edit name & access. Changing scopes does not change the secret, so you can tighten a key's reach without redeploying it.

A request from a key whose scopes exclude the provider is rejected with 403 insufficient_scope before any credit is reserved, so it costs nothing:

{
  "error": {
    "code": "insufficient_scope",
    "message": "This API key is not permitted to call the instagram provider."
  }
}

Scoping is a blast-radius control, not a security boundary between your own services — every key still bills to the same account and shares the same balance.

Rate limits

Every provider enforces a per-key request ceiling, and providers backed by a scarce upstream resource (currently Instagram, eBay and Vinted) set tighter per-key limits plus an account-independent pool cap protecting the shared egress. Normal integrations sit well below these.

Windows are fixed: one minute for the sustained per-key ceiling and for the pool. Keys on a tier with a burst allowance also get a 10-second window of twice the sustained rate, so a poller can catch up after a stall without being able to spend a whole minute's quota in one second.

Reading your limits

Every response that reaches the limiter — successes and errors alike — carries the live numbers for the provider you called, so a client can pace itself from the headers instead of hard-coding ours:

HeaderMeaning
X-RateLimit-LimitYour sustained ceiling per minute for this provider.
X-RateLimit-RemainingRequests left in the current one-minute window.
X-RateLimit-ResetUTC epoch seconds at which that window resets.
X-RateLimit-TierYour key's tier: standard, or firehose.
X-RateLimit-Burst-Limit / -Remaining / -ResetThe 10-second burst window. Only sent on tiers that have one.

Exceeding a limit returns 429 rate_limited with a Retry-After header (seconds until the rejecting window resets) and X-RateLimit-Scope naming which window said no: key (your sustained ceiling), burst (your 10-second window) or pool (the provider is at capacity across all customers). A 429 costs no credits and never touches the upstream.

Tiers

Every key starts on standard — the provider defaults above. firehose is a tier extractr assigns per key for first-party and partner pipelines that must never queue: it raises the sustained ceiling on specific providers and adds the burst window. If you need it, get in touch with your expected request rate per provider.

Failure modes

SituationStatusCode
No key supplied401unauthorized
Key malformed, revoked or unknown401invalid_api_key
Key not scoped for the provider403insufficient_scope
Too many requests429rate_limited

See Errors for the response shape.

On this page