Rate Limits

Rate limits protect the platform from overload and keep things fair for everyone. Anonymous limits are based on your IP address. Authenticated requests are keyed to your API key. Most limits reset every hour.

Anonymous Limits

Without an API key, you can browse and explore freely. Heavier operations like SQL queries and data exports require a free account.

Endpoint TypeRate LimitExample Paths
Browsing & metadata150/hour/v1/datasets, /v1/providers
Search60/hour/v1/search
Data queries30/hour/v1/datasets/{provider}/{dataset}
SQL queriesRequires accountPOST /v1/datasets/{provider}/{dataset}/query
Downloads & exportsRequires account/v1/datasets/{provider}/{dataset}/export

Authenticated Limits

A free account unlocks SQL queries, data exports, and 10x higher limits across the board. See the Authentication guide to get started.

Endpoint TypeRate LimitExample Paths
Search1,000/hour/v1/search
Browsing & metadata500/hour/v1/datasets, /v1/providers
Data queries600/hour/v1/datasets/{provider}/{dataset}
SQL queries60/minutePOST /v1/datasets/{provider}/{dataset}/query
Downloads & exports20/hour/v1/datasets/{provider}/{dataset}/export

Rate Limit Headers

Every API response includes rate limit information in headers:

Response Headers
X-RateLimit-Limit: 150
X-RateLimit-Remaining: 112
X-RateLimit-Reset: 1704067200
X-RateLimit-Limit
Maximum requests allowed in the current window
X-RateLimit-Remaining
Requests remaining in the current window
X-RateLimit-Reset
Unix timestamp when the rate limit resets

Handling Errors

Rate Limit Exceeded (429)

When you exceed the rate limit, the API returns a 429 status code:

429 Too Many Requests
{
"error": "rate_limit_exceeded",
"message": "Rate limit reached. Try again in 42 minutes.",
"retry_after": 2520,
"limit": "150/hour",
"upgrade_message": "Sign up free for 10x higher limits and full data exports.",
"signup_url": "https://tryopendata.ai/signup",
"documentation_url": "https://tryopendata.ai/docs/rate-limits"
}

The retry_after field tells you how many seconds to wait before trying again. The Retry-After header contains the same value.

Authentication Required (403)

SQL queries and data exports return a 403 if you haven't signed in:

403 Forbidden
{
"error": "auth_required",
"message": "SQL queries require a free account. Sign up to start running queries.",
"signup_url": "https://tryopendata.ai/signup",
"documentation_url": "https://tryopendata.ai/docs/authentication"
}

Creating an account is free and takes a few seconds. See the Authentication guide.

Best Practices

  • Check headers - Monitor remaining requests before hitting limits
  • Implement backoff - Use exponential backoff when receiving 429
  • Cache responses - Cache frequently-accessed data locally
  • Batch requests - Combine multiple queries when possible

Python Example with Retry

import time
import requests
def fetch_with_retry(url, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")

Increasing Your Limits

The anonymous limits above are designed for casual browsing. Creating a free account unlocks SQL queries, data exports, and 10x higher rate limits (see the authenticated table above). No credit card needed.

To get started, see the Authentication guide.

Search datasets

Search for datasets or run quick actions