Primary method: X-API-Key header (recommended)
Send your API key in the X-API-Key header on every request:
curl "https://kwery-api.com/v1/candles?symbol=BTCUSDT&interval=1h" \
-H "X-API-Key: kwery_live_abc123"
This keeps keys out of URLs and server logs. Use this method in production.
Convenience method: api_key query parameter
You can also pass the key as a query parameter for quick browser testing or one-off scripts:
curl "https://kwery-api.com/v1/candles?api_key=kwery_live_abc123&symbol=BTCUSDT&interval=1h"
Not recommended in production — keys may appear in logs, referrer headers, and browser history. If both the header and query parameter are present, the header takes priority.
Key format
All keys are prefixed with:
kwery_live_— production keyskwery_test_— development/test keys
This format helps secret scanners (e.g. GitHub) detect leaked keys automatically. Create and manage keys in the Dashboard.
Validation flow
On each request, the API runs through this chain:
- Extract key — From
X-API-Keyheader, or fall back toapi_keyquery parameter if the header is missing. - Format check — If missing, shorter than 10 characters, or longer than 256 characters →
401 invalid_api_key. - Key lookup — SHA-256 hash of the raw key is looked up via 3-layer cache: in-memory → Redis → Supabase DB.
- Revocation and pause check — If the key is revoked, expired, or paused (e.g. subscription payment failed) →
401 api_key_revokedor401 api_key_paused. Paused keys are restored when the invoice is paid or after the account is downgraded to Basic. - Account status — If the account is suspended or deleted →
403 account_suspended. - IP allowlist — If the key has an IP allowlist, the request IP is validated. Mismatch →
401 invalid_api_key. - Rate limits — Per-key RPM/RPH are enforced →
429 rate_limit_exceededwithRetry-Afterheader. - Credit sync — Credit counter is read from Redis (atomic, cross-dyno accurate).
- Credit check — If credits are fully exhausted →
402 credits_exhausted. - Scope validation — If the key has restricted endpoint scopes, the requested endpoint is checked →
403 plan_requiredif out of scope.
All checks pass → the request is served.
Key management
In the Dashboard you can:
- Create and revoke keys — Multiple keys per account. Revoked keys are rejected within seconds.
- IP allowlists — Restrict a key to specific source IPs (e.g. production servers).
- Endpoint scopes — Restrict a key to specific API paths.
Security best practices
- Use the
X-API-Keyheader in production, not the query parameter. - Store keys in environment variables; never in client-side code or public repos.
- Use separate
kwery_live_andkwery_test_keys for production vs development. - Configure IP allowlists for production keys.
- Rotate keys periodically — create a new key, migrate services, then revoke the old one.
Error responses
| Status | Code | When |
|---|---|---|
| 401 | invalid_api_key | Missing, malformed, or unknown key |
| 401 | api_key_revoked | Key revoked or expired |
| 401 | api_key_paused | Subscription payment failed; pay the outstanding invoice or wait until account is downgraded to Basic |
| 403 | account_suspended | Account suspended or deleted |
| 403 | plan_required | Endpoint/feature locked for your tier |
| 402 | credits_exhausted | Monthly credits depleted |
| 429 | rate_limit_exceeded | RPM or RPH exceeded |
Error responses use a standard envelope:
{
"error": "invalid_api_key",
"message": "Missing or invalid API key."
}
For 429 responses, a retry_after value (seconds) is included; the response also sends a Retry-After header.