API Limits

OHLC API Rate Limits and Errors

Know the public limits before you build a data pipeline. This page covers request quotas, response headers, error codes and safe retry behaviour.

Updated 2026-11-02 ? Data refreshed from the AlgoSpecial catalog.

60requests per minute
1,000requests per day
50kmax rows per request
366dmax date range

Public request limits

LimitValueScope
Requests per minute60Per IP address
Requests per day1,000Per IP address
Maximum rows50,000Per request
Maximum date range366 daysPer request

No API key is required for the public tier. The limits apply to the OHLC and data quality endpoints.

Rate limit headers

HeaderMeaning
X-RateLimit-LimitRequests allowed in the current minute
X-RateLimit-RemainingRequests left in the current minute
X-RateLimit-ResetSeconds until the minute window resets
Retry-AfterSeconds to wait after a 429 response

Error codes

StatusMeaningAction
200SuccessUse the response
400Invalid parameter or date rangeFix the request; do not retry unchanged
404Dataset not foundCheck symbol and timeframe
413More than 50,000 rowsNarrow the date range or raise the timeframe
429Rate limit exceededWait for Retry-After
500Server errorRetry later with backoff

Best practices for large pulls

  • Cache successful responses locally instead of requesting the same range twice.
  • Split multi-year M1 requests into monthly windows.
  • Use higher timeframes when you do not need tick-sensitive bars.
  • Respect Retry-After on 429; do not use a tight retry loop.
  • Treat 413 as a request design problem, not a transient error.
  • Keep your client timeout above the expected response time for large JSON payloads.

Request examples

Inspect headers

curl -I "https://www.algospecial.com/api/ohlc.php?symbol=XAUUSD&tf=M15&from=2026-01-01&to=2026-01-31"

Retry a 429 safely

import time
import requests

url = "https://www.algospecial.com/api/ohlc.php"
params = {
    "symbol": "EURUSD",
    "tf": "M15",
    "from": "2026-01-01",
    "to": "2026-01-31",
}

for attempt in range(3):
    r = requests.get(url, params=params, timeout=30)
    if r.status_code != 429:
        r.raise_for_status()
        print(r.json()["rows"])
        break
    time.sleep(int(r.headers.get("Retry-After", "60")))
else:
    raise SystemExit("Rate limit retry exhausted")

Reduce rows with a higher timeframe

# Instead of a multi-year M1 request, use H1 for lower-volume research.
curl "https://www.algospecial.com/api/ohlc.php?symbol=XAUUSD&tf=H1&from=2025-01-01&to=2025-12-31"

All timestamps are broker server time. Some legacy forex exports return 0 for TickVolume and Spread because those fields were not present in the source feed.

Rate Limits FAQ

Do I need an API key?

No. The public tier is anonymous and rate-limited per IP address.

What happens after 60 requests in a minute?

The API returns 429 with Retry-After. Wait for that many seconds before retrying.

Why did I get 413?

The requested range would return more than 50,000 rows. Narrow the dates or use a higher timeframe.

Are limits per endpoint or shared?

The public limits apply to the API surface; the OHLC and quality endpoints share the same per-IP allowance.

Can I request multiple symbols in one call?

No. One request returns one symbol and one timeframe. Make separate requests and cache each result.

🚀 Invite friends — Earn $5 You both get $5 credit on Go Ad · opencode.ai AI-Powered Coding Agent — Try Free Build apps, fix bugs & ship faster with opencode. Get $5 free credit when you join. × Ad · quo.com QuoPhone — $20 Visa Gift Card Free Sign up to Quo, subscribe 3 months, get a $20 Visa gift card. Atif's referral gift for you. ×