Rate Limits
Postato API limits and social network quotas.
Rate limits
Two layers matter here. Postato's own limits protect our infrastructure and ensure fair use. The target social network's limits are separate, harder to predict, and usually much tighter.
Postato API limits
Bucketed per tenant, measured per minute:
| Endpoint family | Default limit |
|---|---|
POST /posts | 120 / min |
GET /posts, GET /posts/{id} | 600 / min |
Media uploads (POST /media, presigned PUTs) | 60 / min |
| All other endpoints | 600 / min |
Limits are higher on paid tiers. If you're hitting them regularly, talk to us; we'd rather lift the cap than have you work around the limit.
Response
When a limit fires:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{ "error": "rate_limited", "message": "Retry in 12 seconds" }Retry-After is in seconds. Wait at least that long; waiting longer is also fine.
Best practice
- Back off on the first 429 instead of hammering.
- Spread scheduled publishing over minutes, not seconds. 100 posts queued for the same
scheduledAtwill trip the limit at fire time. See Staggered publishing. - When queuing many posts, add jitter to
scheduledAt(random offset of a few minutes) so they don't all fire simultaneously.
Social network limits
The social networks each have their own publishing quotas. Postato does not lift these. We pass requests through, and if the network rejects for rate reasons, the post fails with an error from that origin.
Typical daily caps (approximate, platforms adjust these without notice):
| Platform | Per account, per day |
|---|---|
| X / Twitter | ~2,400 tweets |
| ~25 posts | |
| ~100 posts | |
| TikTok | ~10 videos |
| YouTube | Quota units vary; a video upload costs ~1,600 |
These are ceilings, not recommendations. Human-quality cadence is much lower.
When Postato throttles a platform call
If the target network rate-limits Postato's delivery attempt, our worker retries with backoff for up to ~15 minutes. After that, the post fails with an error of origin: "platform", code: "RATE_LIMITED", retryable: true. Resubmit after a break.
Detecting trouble early
- Log
X-RateLimit-Remainingresponse headers. Postato includes them on 2xx responses so you can watch the bucket drain. - Watch for clusters of 429s in your observability; usually means a cron fires too aggressively. Stagger it.