ofapisv1
info

Updated

OnlyFans API Rate Limits

OnlyFans API rate limits cap how fast you can send requests, measured in requests per minute (rpm). They are separate from your monthly credit budget: you can have credits left and still be throttled if you burst too hard. ofapis sets the ceiling by plan so a single noisy integration can't destabilize a linked account.

Limits by plan

Plan Rate limit Monthly credits Linked accounts
Free 60 rpm 250 1
Starter 100 rpm 30,000 1
Pro 500 rpm 120,000 5
Enterprise Negotiated Volume pricing Negotiated

The rpm ceiling is your burst throughput. Credits are your volume budget over the month. The two diverge sharply, and the clearest case is a mass send: creating, previewing and triggering a mailing is three requests against your rpm, while the run behind it debits one credit per recipient. Twenty thousand fans is three requests and twenty thousand credits.

How the window actually works

The counter is a fixed 60-second window held per API token, not per account and not per IP.

There is no separate concurrency cap. Fifty parallel requests are simply fifty slots consumed at once, so on Free that is most of the minute gone in whatever time your client takes to open fifty sockets. Rate is the only dimension the gateway polices.

Because the bucket is keyed on the token, two tokens on the same plan get two independent windows — but they share one credit balance and one set of linked accounts, so this buys burst room, not volume. Issuing a token per service is covered under authentication.

Read the headers, don't wait for the 429

Every response carries the state of your current window:

Header Meaning
X-RateLimit-Limit Requests allowed per window — 60, 100 or 500
X-RateLimit-Remaining Slots left, floored at 0
X-RateLimit-Reset Unix epoch (seconds) at which the window rolls
Retry-After On a 429 only: whole seconds to wait, never less than 1

Retry-After is derived from the reset timestamp, so it can never exceed 60 and is usually far less. That makes exponential backoff the wrong first instinct here: the server already knows exactly how long you must wait, and doubling past it only wastes throughput.

To see where you stand before kicking off a batch, a single curl and jq call from the terminal prints all three headers without any code at all.

Spreading the remaining slots over the remaining time is better than sprinting into the wall:

import time

def pace(resp):
    """Sleep just enough to spread what's left of the window evenly."""
    remaining = int(resp.headers.get("X-RateLimit-Remaining", 1))
    reset = int(resp.headers.get("X-RateLimit-Reset", 0))
    gap = max(reset - time.time(), 0.0)
    if remaining <= 0:
        time.sleep(gap + 0.25)        # window is closed; wait it out
    elif gap > 0:
        time.sleep(gap / (remaining + 1))

Call pace(r) after every response and a worker self-regulates: it runs flat out while slots are plentiful and glides into the reset when they aren't, without ever producing a 429.

Most HTTP stacks already have a retry layer that will do the waiting for you once you feed it Retry-After — Polly in the C# quickstart, Faraday middleware in the Ruby client, and the error enum that separates a retryable 429 from a fatal 422 in the Rust quickstart.

The arithmetic

Sustained, a ceiling is just a minimum gap between requests.

Plan Ceiling Gap per request Requests per hour
Free 60 rpm 1,000 ms 3,600
Starter 100 rpm 600 ms 6,000
Pro 500 rpm 120 ms 30,000

Now page a real audience. limit is clamped server-side to 1–100 and offset starts at 0, so a creator with 10,000 subscribers is 100 calls at limit=100. On Free that is 100 seconds and spans two windows; on Starter roughly one window; on Pro about 12 seconds. It also costs 100 credits — 40% of the Free plan's entire 250-credit month for one full sweep of the subscriber list.

Two paging details change the maths. Lists default to limit: 10, not 20, so a 5,000-member list is 500 calls unless you raise it — pass limit=100 and it becomes 50. Message history doesn't use offset at all: it pages backwards with the olderThanMessageId cursor, which means you can't parallelise it across offsets and the gap per request is the real floor on how fast a backfill runs.

The slowest thing in your pipeline probably isn't the rate limit, though. A mailing run dispatches one message every 500 ms server-side, so 20,000 recipients take about three hours to deliver — none of it against your rpm, because the trigger was a single call. Schedule a timed PPV drop around that three-hour figure rather than around your request ceiling.

Staying under the ceiling by design

Prefer webhooks over polling: one message.received delivery replaces a poll loop that would otherwise burn slots and credits finding nothing. Cache anything slow-moving — profile details and subscriber rosters don't change between two requests a second apart. On Pro with five linked accounts, stagger per-account jobs instead of firing all five at once, since they share one token bucket — the agency operations guide works through what that staggering looks like across a roster. And when you genuinely need the throughput, moving up a plan is cheaper than a retry storm; the cost breakdown has the per-call maths.

A 429 is free — it never reaches metering — but it is not harmless, because the slot it consumed is gone and the work still has to happen later. Full handling details for 429 alongside every other status are on the error codes page.

FAQ

What is the rate limit on the free OnlyFans API plan?

The Free plan allows 60 requests per minute per token, which works out to one request per second sustained. Starter raises it to 100 rpm and Pro to 500 rpm; Enterprise is negotiated. The ceiling is enforced independently of your monthly credit allowance.

Is the rate-limit window a rolling 60 seconds?

No, it's a fixed window anchored to your first request. The window opens when a request arrives with no window active and closes exactly 60 seconds later, so your full allowance becomes available again at the X-RateLimit-Reset timestamp rather than draining away gradually. Read that header instead of assuming clock-minute boundaries.

Do two API tokens get two rate limits?

Yes. The counter is bucketed per token, so a scheduler and a chatbot holding separate tokens never throttle each other. They still draw on the same credit balance and the same linked accounts, so this raises your burst ceiling without raising your monthly volume.

How long can Retry-After be?

At most 60 seconds, and in practice however long is left of the current window — it's computed as the reset timestamp minus now, with a floor of one second. Sleep for exactly that and retry; there's no benefit to doubling it, because the server has already told you when the window rolls.

Does paging a large subscriber list risk a 429?

Only if you page faster than the ceiling. At limit=100 a 10,000-subscriber account is 100 requests, which fits inside a single Starter or Pro window and takes two windows on Free. Pace off X-RateLimit-Remaining and the job finishes without a single rejected call.

Start free · Error codes · Set up webhooks · API docs

Related guides

All guides
Start free — 250 credits, no card
Generate a token and make your first call in minutes.
Get started