Skip to main content

Rate Limiting

The geocodeme.net API uses a two-level limiting system to ensure fair usage:

  1. Per-second rate limit: burst protection using a Redis sliding window. Limits how many requests you can make per second.
  2. 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​

PlanRate Limit (req/s)Credit Quota
Free13,000 / day
Startup10150,000 / month
Growth15500,000 / month
Pro251,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:

HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed per second for your plan
X-RateLimit-RemainingNumber of requests remaining in the current per-second window
X-RateLimit-ResetUnix timestamp when the per-second rate limit resets
X-RateLimit-Monthly-LimitCredit quota for the current window (monthly; daily on Free)
X-RateLimit-Monthly-RemainingCredits remaining in the current quota window
X-RateLimit-Monthly-ResetUnix timestamp when the quota window resets (1st of next month 00:00 UTC; next midnight UTC on Free)
X-RateLimit-Monthly-WarningSet to true once you have used ≥ 80% of your quota window
Retry-AfterOnly on 429 responses: number of seconds to wait before retrying
note

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.

tip

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.