For self-serve customers:
| Window | Limit |
|---|---|
| Per minute | 60 requests |
| Per day | 1,000 requests |
| Enterprise customers have higher limits defined in their subscription agreement. Contact support if you need increased limits. |
The API returns 429 Too Many Requests with two headers:
| Header | Meaning |
|---|---|
Retry-After |
Seconds to wait before retrying |
X-RateLimit-Limit |
Your limit for the current window |
Do not immediately retry on a 429. Use exponential backoff — wait progressively longer between retries:
# curl doesn't retry automatically — wrap it in a shell loop
while true; do
STATUS=$(curl -s -o response.json -w "%{http_code}" \
-X POST 'https://api.ocean.io/v3/search/companies' \
-H 'X-Api-Token: YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "size": 50 }')
[ "$STATUS" != "429" ] && break
WAIT=$(grep -i "retry-after" response.json | awk '{print $2}' || echo 1)
sleep "$WAIT"
doneimport time
import requests
def request_with_backoff(url, headers, payload, max_retries=5):
for attempt in range(max_retries):
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 429:
return response
retry_after = int(response.headers.get("Retry-After", 2**attempt))
time.sleep(retry_after)
raise RuntimeError("Rate limit retries exhausted")async function requestWithBackoff(url, headers, body) {
while (true) {
const res = await fetch(url, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (res.status !== 429) return res;
const wait = parseInt(res.headers.get('Retry-After') ?? '1', 10);
await new Promise(r => setTimeout(r, wait * 1000));
}
}size parameter to request only as many results as you needfields parameter to request only the fields you need — this reduces latency and can help with throughputdailyLimitRateLeft field shows how many requests remain today