Docs › API reference › Rate limits

API rate limits, 429 responses and Retry-After

How many requests you can make per minute, how OmniPosts counts them, and what to do when you get a 429.

Updated

OmniPosts limits how fast you can call the API. The limits protect everyone's posting from a runaway script. Normal use does not come near them.

The buckets

Every request is counted in one bucket. Counting uses fixed windows: a one-minute bucket starts fresh at the start of each clock minute.

Bucket Limit Window Counted per Which requests
Read 600 1 minute organization Every GET (and HEAD)
Write 60 1 minute organization Every other write: POST, PUT, PATCH, DELETE
Autosave 30 1 minute organization PATCH /v1/ideas/{id} only
Media 10 1 minute organization Writes under /v1/media: uploads and PATCH /v1/media/{id}
Auth 20 1 minute client IP address /v1/auth/*: sign up, log in, log out
Auth, per account 20 1 minute email address POST /v1/auth/login, on top of the IP limit
Export 3 1 hour organization GET /v1/settings/export, on top of the Read bucket

"Per organization" means everything you do with any key or session of one organization shares the bucket. Two keys in the same organization do not get two budgets.

The Read, Write, Autosave and Media counts are kept per API server. If OmniPosts runs more than one API server, each one allows its own budget, so the real ceiling can be higher than the number above, never lower. Auth and Export are shared across servers.

Requests that fail to authenticate (401) are not counted.

The beta waitlist form on the pricing page (POST /waitlist) is not part of the API. It has its own limit of 5 attempts an hour per client address, and answers with a redirect back to the page instead of a 429.

Headers

Header When Meaning
X-RateLimit-Remaining Every request that was counted, not only a refused one Requests left in the current window. 0 on a refusal
Retry-After Every 429 Whole seconds until the current window ends. At least 1
HTTP/1.1 200 OK
X-RateLimit-Remaining: 587

What a 429 looks like

The export and log-in limits have their own wording in message (for example, how many exports you can download an hour), with the same code and the same Retry-After.

HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Remaining: 0
Content-Type: application/json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Wait a moment and try again."
  }
}

What to do

  • Wait Retry-After seconds, then try again. Do not retry in a tight loop.
  • Watch X-RateLimit-Remaining and slow down before it reaches 0.
  • To post to many channels, put them in one post with several targets. One call to POST /v1/groups counts once, however many channels it names.
  • Use an Idempotency-Key on every POST /v1/groups, so retrying after a 429 or a timeout is safe. See Idempotency.
  • Use webhooks instead of polling for results.