Download rate limit?

I keep getting 429 when trying to download subtitles via API. I’m on the Basic plan with 50rps and 15k downloads per 24h. Does the download server have a separate rate limit? If so, would you mind sharing what it is? Thank you.

Anecdotally, I’m not even able to download at a rate of 5 per second. Code:

const res = await fetch(response.link, {
  headers: { ‘Api-Key’: apiKey, ‘User-Agent’: USER_AGENT },
});

Hi Ilya,

Thank you for reaching out. On the Basic plan you should indeed have 50 requests per second available, so hitting 429 at only 5/sec is unexpected.

A few things to check:

First, please look at the rate limit headers in your responses — they’ll tell you what the server is actually seeing:

x-ratelimit-limit-second
x-ratelimit-remaining-second
ratelimit-reset

This will help clarify whether the server is recognising your Basic plan limits or applying defaults. Also note that the rate limit applies mostly to search — the download endpoint may behave differently since it generates temporary links with an expiry.

For more details on rate limiting and headers, please see our Getting Started guide: https://opensubtitles.stoplight.io/docs/opensubtitles-api/e3750fd63a100-getting-started

To help us debug further, could you share some logs showing the full response headers from a few consecutive download requests? That way we can see exactly what limits are being applied and what’s triggering the 429.

Thanks for your reply. Here’s a sample request and response:

Request GET:

https://www.opensubtitles.com/download/2747C3F3F93F161E372F6F3C3A758B8CBF2C36472936038EDDFD1E1D77C6F322599577E815515CDF6E2472B048DE98051814FB1E39AEAD5920ED03FFE01ADCA73ABD38902BC65E407517D38B4B6C79736755E70271A244A5610D85AA63978100A3FA72FEEC99F7FAEED6AF878AB324291BBEF007F0B9545D31257839459A4404CCBEB22D87D3DD3B9B780FFE0011A9E3BE6D90F7249EF7AC90A1F50010F14CE358CB85FF4D3E4FC7390A4CAA7CCC5E5770B2B41A60EF73F34F7FC98E1636D56AD0F98349255538E9C691E1C8CDF724F407F58A91B039D765C2C5E7478B4AD336AE239738B0FDF2B67DAC773395070D46F908CB599250AD053ADADF260857C98671EF28328F44AB220FA350A5553C29A42E19393A5209342B/subfile/Le%20roi%20lion%202.srt

Request headers:

{
  "Api-Key": "<redacted>",
  "User-Agent": "<redacted> v0.0.1"
}

Response headers:

{
  "access-control-allow-origin": "*",
  "age": "238",
  "alt-svc": "h3=\":443\"; ma=86400",
  "cache-control": "public, max-age=3155695200",
  "cf-cache-status": "HIT",
  "cf-ray": "9e1494034ea5da21-CDG",
  "connection": "keep-alive",
  "content-encoding": "br",
  "content-security-policy": "default-src 'self'; font-src 'self' fonts.googleapis.com code.cdn.mozilla.net https: data:; img-src 'self' image.tmdb.org m.media-amazon.com ia.media-imdb.com https: data:; object-src 'self' forum.opensubtitles.com embed.tawk.to; form-action 'self' forum.opensubtitles.com localhost:4200 www.opensubtitles.com tst.yabo-concept.ch ai.opensubtitles.com; frame-src 'self' sbl.onfastspring.com opensubtitles.stoplight.io *.opensubtitles.com opensubtitles.tawk.help forum.opensubtitles.com opensubtitles.test.onfastspring.com opensubtitles.onfastspring.com *.cloudfront.net api.blink.net *.tawk.to tawk.to test.blink.net blink.net www.recaptcha.net www.google.com www.youtube.com sender.cleverwebserver.com c.clvrads.com; connect-src 'self' srv.tunefindforfans.com region1.google-analytics.com bam.eu01.nr-data.net opensubtitles.test.onfastspring.com opensubtitles.onfastspring.com *.cloudfront.net rb-dev:8082 cana.local:8082 localhost:8082 *.test.resolver.perfops.net *.tawk.to wss://*.tawk.to cdn.datatables.net www.google-analytics.com www.gstatic.com https://cdn.datatables.net; base-uri 'self' test.blink.net api.blink.net blink.net *.blink.net; frame-ancestors 'self' forum.opensubtitles.com opensubtitles.onfastspring.com opensubtitles.test.onfastspring.com; script-src 'self' *.cloudfront.net srv.tunefindforfans.com bam.eu01.nr-data.net www.google.com cdn.datatables.net www.recaptcha.net www.google-analytics.com sender.cleverwebserver.com https: 'unsafe-inline' 'unsafe-eval'; style-src 'self' cdnjs.cloudflare.com https: 'unsafe-inline'",
  "content-type": "text/plain; charset=utf-8",
  "date": "Tue, 24 Mar 2026 09:16:38 GMT",
  "etag": "W/\"889099b8e1880bb40185f994ebd20308\"",
  "last-modified": "Sat, 01 Jan 2011 00:00:00 GMT",
  "nel": "{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}",
  "referrer-policy": "strict-origin-when-cross-origin",
  "report-to": "{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=faqdTWQQFodhZNU10%2Fp0K7X3zxZp7300ZvVJj8vq%2Fqga1k5pNXEKhBqNkHbjxCGhI2bNoVPUhjWvnCAnss5%2Bh8aj7WSlEj0c7Yof2BiRaxti4KoxnQ%3D%3D\"}]}",
  "server": "cloudflare",
  "strict-transport-security": "max-age=15552000; includeSubDomains; preload",
  "transfer-encoding": "chunked",
  "vary": "Accept",
  "x-cache-backend": "rb2",
  "x-content-type-options": "nosniff",
  "x-debug-method": "GET",
  "x-debug-url": "/download/2747C3F3F93F161E372F6F3C3A758B8CBF2C36472936038EDDFD1E1D77C6F322599577E815515CDF6E2472B048DE98051814FB1E39AEAD5920ED03FFE01ADCA73ABD38902BC65E407517D38B4B6C79736755E70271A244A5610D85AA63978100A3FA72FEEC99F7FAEED6AF878AB324291BBEF007F0B9545D31257839459A4404CCBEB22D87D3DD3B9B780FFE0011A9E3BE6D90F7249EF7AC90A1F50010F14CE358CB85FF4D3E4FC7390A4CAA7CCC5E5770B2B41A60EF73F34F7FC98E1636D56AD0F98349255538E9C691E1C8CDF724F407F58A91B039D765C2C5E7478B4AD336AE239738B0FDF2B67DAC773395070D46F908CB599250AD053ADADF260857C98671EF28328F44AB220FA350A5553C29A42E19393A5209342B/subfile/Le%20roi%20lion%202.srt",
  "x-debug-vcl-deliver": "RUNNING",
  "x-download-options": "noopen",
  "x-frame-options": "SAMEORIGIN",
  "x-permitted-cross-domain-policies": "none",
  "x-ratelimit-limit-minute": "240",
  "x-ratelimit-limit-second": "6",
  "x-ratelimit-remaining-minute": "1196",
  "x-ratelimit-remaining-second": "2",
  "x-ratelimit-source": "varnish",
  "x-request-id": "c5fe6c20-4deb-4386-8b25-8f9134ea9cb6",
  "x-runtime": "0.012676",
  "x-var-cache": "MISS",
  "x-vcl-version": "2026-02-07-v7",
  "x-via": "lb1",
  "x-xss-protection": "1; mode=block"
}

I see the following rate-limit response headers:

x-ratelimit-limit-minute: 240
x-ratelimit-limit-second: 6
x-ratelimit-remaining-minute: 1196
x-ratelimit-remaining-second: 2
x-ratelimit-source: varnish

One thing that caught my eye: How can I have 240 per minute, but also have 1196 remaining for the minute? For downloads, there was no ratelimit-reset.

For the rest of the API, I get x-ratelimit-limit-second: 50.

Does this mean that, even with a Basic plan, there’s a 6RPS limit for downloading subtitles? Are the two rate limits (and endpoints) completely separate?

Thanks again.

Thanks for the detailed logs — that’s really helpful.

So the key thing here is that the download URL you’re calling (the long /download/... URL) is not part of the API itself. That URL is generated by the /download API endpoint, and then it’s served and cached through Cloudflare/Varnish — there’s no authorization check on it, it’s just a static file link at that point.

The rate limit headers you’re seeing on those download URLs (x-ratelimit-limit-second: 6, x-ratelimit-source: varnish) are from the Varnish caching layer, not from our API. That’s separate from your API plan limits — which is why you see 50rps on actual API calls but 6rps on the file downloads.

As for the x-ratelimit-remaining-minute: 1196 being higher than the 240 limit — that looks like a quirk of the Varnish/caching layer reporting, not something we control on the API side.

So to summarize: yes, the API rate limit and the download file serving are completely separate. Your Basic plan 50rps applies to API calls (search, /download endpoint to generate the link, etc.), while the actual file download URLs go through a different layer with its own limits.

If you’re hitting 429s on the file downloads specifically, try pacing those requests to stay within the limits shown in the Varnish headers.

2 Likes

Understood. Thanks for the clarification!