Rate Limiting
The geocodeme.net API uses a two-level limiting system to ensure fair usage:
- Per-second rate limit: burst protection using a Redis sliding window. Limits how many requests you can make per second.
- Credit quota: volume control in credits (each endpoint has a weight: a geocode costs 1 credit, an isochrone 10). Paid plans get a monthly envelope resetting on the 1st; the Free plan gets a daily envelope resetting at midnight UTC.
Plan Tiers
| Plan | Rate Limit (req/s) | Credit Quota |
|---|---|---|
| Free | 1 | 3,000 / day |
| Startup | 10 | 150,000 / month |
| Growth | 15 | 500,000 / month |
| Pro | 25 | 1,500,000 / month |
See current pricing for plan details and prices, and the Credits & quotas page for the per-endpoint weights.
Response Headers
Every API response includes these rate limiting headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed per second for your plan |
X-RateLimit-Remaining | Number of requests remaining in the current per-second window |
X-RateLimit-Reset | Unix timestamp when the per-second rate limit resets |
X-RateLimit-Monthly-Limit | Credit quota for the current window (monthly; daily on Free) |
X-RateLimit-Monthly-Remaining | Credits remaining in the current quota window |
X-RateLimit-Monthly-Reset | Unix timestamp when the quota window resets (1st of next month 00:00 UTC; next midnight UTC on Free) |
X-RateLimit-Monthly-Warning | Set to true once you have used ≥ 80% of your quota window |
Retry-After | Only on 429 responses: number of seconds to wait before retrying |
The Monthly-* header names are kept for compatibility: on the Free plan they describe today's window (limit 3,000, reset at midnight UTC).
Inspect rate limit headers with:
curl -I -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/geocode?q=Paris"
Handling 429 Errors
When you exceed a limit, the API returns HTTP 429 with one of two error codes:
Rate Limit Exceeded (per-second)
The retry_after field indicates how many seconds to wait:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 1 second",
"retry_after": 1
}
}
Implement exponential backoff:
import time
import requests
def geocode_with_retry(url, headers, params, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers, params=params)
if response.status_code != 429:
response.raise_for_status()
return response
try:
retry_after = response.json()["error"]["retry_after"]
except (ValueError, KeyError):
retry_after = 1 # default backoff if response isn't valid JSON
time.sleep(retry_after * (2 ** attempt))
raise requests.exceptions.HTTPError(
f"Rate limit exceeded after {max_retries} retries", response=response
)
Quota Exceeded (credits)
The quota_reset field is a Unix timestamp indicating when your quota window resets (next midnight UTC on Free, 1st of next month on paid plans):
{
"error": {
"code": "QUOTA_EXCEEDED",
"message": "Quota exceeded. Upgrade your plan to continue.",
"quota_reset": 1753056000,
"upgrade_url": "https://geocodeme.net/dashboard/billing"
}
}
When your quota is exhausted, you can either upgrade your plan or wait for the window reset.
Cache geocoding results locally (e.g. Redis, in-memory) to avoid redundant API calls and preserve your credits, and remember that server-side (5xx) failures are automatically refunded.