Errors & rate limits
HTTP status codes, error format, and how rate limiting works.
HTTP status codes
| Status | Meaning | What to do |
|---|---|---|
| 200 | OK | Request succeeded. Check the response body for results. |
| 400 | Bad request | Missing or invalid parameters. Check q, lat, lon are present and valid. |
| 401 | Unauthorized | Invalid or missing API key. Check your Authorization header or api_key parameter. |
| 403 | Forbidden | API key suspended or revoked. Check your account at geoheim.com/dashboard. |
| 429 | Rate limited | Too many requests. Back off and retry after X-RateLimit-Reset timestamp. |
| 500 | Server error | Something broke on our end. Check status.geoheim.com. Retry with backoff. |
Error response format
All errors return a JSON object with an error field:
401 — Invalid API key
{
"error": "Invalid API key",
"code": 401
}429 — Rate limited
{
"error": "Rate limit exceeded",
"code": 429,
"retry_after": 1711324800
}400 — Missing parameter
{
"error": "Missing required parameter: q",
"code": 400
}Rate limiting
Every response includes rate limit headers:
X-RateLimit-Limit: 33334 # Your daily quota X-RateLimit-Remaining: 32891 # Requests left today X-RateLimit-Reset: 1711324800 # Unix timestamp when counter resets
Handling 429 responses
retry.py
import time, requests
def geocode(query, retries=3):
for attempt in range(retries):
resp = requests.get(
"https://api.geoheim.com/search",
params={"q": query, "format": "json"},
headers={"Authorization": "Bearer hk_live_…"},
)
if resp.status_code == 429:
reset = int(resp.headers.get("X-RateLimit-Reset", 0))
wait = max(reset - time.time(), 1)
time.sleep(wait)
continue
return resp.json()
raise Exception("Rate limited after retries")No result vs error
A search that finds nothing is not an error. The HTTP status is still 200:
/search — no results
[] # Empty array, HTTP 200
/reverse — no result at coordinates
{"error": "Unable to geocode"} # HTTP 200, check for error fieldSelf-hosted instances
No rate limits. No API key required. No 401/403/429 errors. Just the same API with no restrictions.