If you publish programmatically, two separate rate limits apply and only one of them is in your control.
The two levels
The platform’s limit. Every social network limits how much any application can do on its API, with its own window, its own headers and its own behaviour when exceeded. These differ per platform and change without much notice.
Your provider’s limit. If you publish through a unified API, that service also has a limit, usually tied to your plan.
The second is easy to read and plan against. The first is the one that bites, because you never see it directly if you’re using a unified API. The provider absorbs it, which is a large part of what you’re paying for, but it doesn’t disappear: a platform throttling everyone still means your post is delayed.
Design for delay, not just for errors
The most common mistake in a publishing pipeline is treating “accepted” as “published”.
On several platforms, submitting a post returns success and the actual publishing happens afterwards. So the failure arrives later, out of band, long after your request returned 200. If your data model has only “sent” and “failed”, there’s nowhere to put “we think this is publishing”.
Design for three states, and make the pending one visible.
Practical rules
Back off exponentially. On a 429, wait and retry with an increasing delay. Immediate retries make the situation worse and can extend a throttle.
Cap your retries. A pipeline retrying forever is how a quota disappears in minutes. Give up, log loudly, and let a human look.
Never retry a create blindly. If a create request times out, you don’t know whether it succeeded. Retrying can produce duplicate posts, which is worse than the original failure. Check before retrying, or use an approach that makes the retry safe.
Batch where an endpoint supports it. One request creating many posts costs one request. The same work as fifty individual calls costs fifty.
BulkPublish’s own limits

| Free | Pro | Business | |
|---|---|---|---|
| API requests/day | 30 | 5,000 | 50,000 |
| API keys | 1 | 5 | 10 |
| Posts | 3/day | 30/day | Unlimited |
The free tier’s 30 requests a day is deliberately sized for evaluating the API and running something light and personal. It is not enough to run a real pipeline, and a loop without backoff will exhaust it in seconds.
Note that API requests and posts are separate limits. Listing channels, checking status and uploading media all consume requests without creating a post, so the request budget goes further than the post count suggests only if you use it carefully.
Multiple keys are for separation, not more capacity
Paid plans include several API keys, and the reason isn’t extra throughput. It’s so different things can hold different credentials: your production pipeline, a staging environment, an AI agent.
The value shows up when something goes wrong. You revoke one key at 2am rather than rotating the one credential everything shares.
A sensible shape for a publishing job
- Look up channels once at startup, not per post
- Upload media, then create posts referencing the ids
- Use batch endpoints where they exist
- Handle 429 with exponential backoff and a retry cap
- Log every failure with the response body, because nobody is watching
The short version
Two limits apply: the platform’s, which you can’t see through a unified API, and your provider’s, which you can. Back off exponentially, cap retries, never blindly retry a create, batch where you can. And treat “accepted” as a state distinct from “published”, because on several platforms it genuinely is.