Every request must include your API key. You can send it in two ways:
1. X-API-Key header (recommended)
Send your API key in the X-API-Key header. This keeps keys out of URLs, logs, and referrers. Use this method in production.
curl "https://kwery-api.com/v1/candles?symbol=BTC&interval=1h" \
-H "X-API-Key: kwery_live_YOUR_KEY"
Python
import requests
resp = requests.get(
"https://kwery-api.com/v1/candles",
params={"symbol": "BTC", "interval": "1h"},
headers={"X-API-Key": "kwery_live_YOUR_KEY"},
)
JavaScript
const res = await fetch("https://kwery-api.com/v1/candles?symbol=BTC&interval=1h", {
headers: { "X-API-Key": "kwery_live_YOUR_KEY" },
});
2. api-key query parameter
You can also pass the key as the api-key query parameter. Use this for quick tests, browser checks, or one-off scripts. Not recommended in production — keys may appear in server logs, referrer headers, and browser history.
curl "https://kwery-api.com/v1/candles?api-key=kwery_live_YOUR_KEY&symbol=BTC&interval=1h"
If both the header and the query parameter are present, the header takes priority.
Key format
Keys are prefixed as follows:
| Prefix | Use |
|---|---|
kwery_live_ | Production |
kwery_test_ | Development / testing |
Create and manage keys in the Dashboard. The full key is shown only once at creation; store it securely (e.g. in environment variables).
How the API validates your key
On each request the API:
- Reads the key — From the
X-API-Keyheader, or from theapi-keyquery parameter if the header is missing. - Checks format — Missing, too short (< 10 chars), or too long (> 256 chars) →
401 invalid_api_key. - Looks up the key — SHA-256 hash is resolved via cache (in-memory → Redis → database).
- Checks status — Revoked, expired, or paused (e.g. payment failed) →
401 api_key_revokedor401 api_key_paused. - Checks account — Suspended or deleted →
403 account_suspended. - Checks IP allowlist — If configured, request IP must match →
401 invalid_api_keyotherwise. - Enforces rate limits — Per-second and per-minute →
429 rate_limit_exceededwithRetry-After. - Checks credits — Exhausted →
402 credits_exhausted. - Checks scopes — If the key has restricted endpoints, the requested path must be allowed →
403 plan_requiredotherwise.
If all checks pass, the request is served.
Key management
In the Dashboard you can:
- Create and revoke keys — Multiple keys per account; revocation takes effect within seconds.
- Set IP allowlists — Restrict a key to specific source IPs (e.g. production servers).
- Restrict endpoint scopes — Limit 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, switch services over, 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 invoice or wait for downgrade |
| 403 | account_suspended | Account suspended or deleted |
| 403 | plan_required | Endpoint or feature requires a higher plan |
| 402 | credits_exhausted | Monthly credits depleted |
| 429 | rate_limit_exceeded | Per-second or per-minute limit exceeded |
Errors use a consistent JSON envelope:
{
"error": "invalid_api_key",
"message": "Missing or invalid API key."
}
For 429 responses, the body includes retry_after (seconds) and the response sends a Retry-After header.