API

Rate limits

How Zilfu throttles API and publishing requests, and how to handle a 429 response.

Updated Jul 27, 2026

Zilfu caps how often each token and user can call the API, so a runaway script can't overload the platform or get our social integrations flagged for abusive traffic. Normal use — composing, scheduling, listing a queue — never comes close. The ceilings only bite when a client misbehaves.

Two limits apply to API and MCP traffic: a global api ceiling on every authenticated request, and a tighter publish ceiling on the endpoints that create or reshape posts.

The limits

Limit Scope Cap Keyed by
api Every /api/* request 120 / min API token, falling back to user, then IP
publish Endpoints that create or reshape posts 30 / min User

The two stack: a request to a publishing endpoint counts against both. In practice publish is the ceiling that bites first.

API requests

Every authenticated request to /api/* counts against the api limiter, capped at 120 requests per minute.

The bucket is keyed per personal access token, so each token you create under Settings → API tokens earns its own independent quota. If a noisy automation is eating its budget, moving it onto a second token gives it a fresh 120/min without touching your other integrations.

The MCP server authenticates with the same token as the REST API, so MCP traffic and direct API calls made with one token share a bucket.

Publishing

The publish limiter caps 30 requests per minute per user across:

Endpoint What it does
POST /api/spaces/{space}/posts Create posts — immediate, scheduled, or queued
PUT /api/spaces/{space}/posts/{post} Update a post
POST /api/spaces/{space}/posts/{post}/retry Retry a failed post
POST /api/spaces/{space}/posts/{post}/comment Schedule a first comment

This bucket is keyed by user rather than by token, so splitting a publishing workload across several tokens on the same account does not raise the ceiling. To backfill a large batch of scheduled posts, spread the work across more than one minute.

Hitting a limit

Exceeding a limit returns HTTP 429 Too Many Requests:

{
  "message": "Too Many Requests"
}

Every response, throttled or not, carries headers describing the bucket:

Header Meaning
X-RateLimit-Limit Maximum requests allowed in the current window
X-RateLimit-Remaining Requests still available in the current window
Retry-After Seconds until the bucket frees up — 429 responses only
X-RateLimit-Reset Unix timestamp of when the bucket frees up — 429 responses only

Where both limiters apply, the headers describe the one that was hit, usually publish.

Handling a 429

Retrying immediately after a 429 keeps failing and can extend how long you stay throttled. Wait for Retry-After before the next attempt.

  • Respect Retry-After. Sleep at least that many seconds before reissuing the request.
  • Back off exponentially on repeated failures — double the wait each time, cap it somewhere sensible like 60 seconds, and give up after a handful of attempts.
  • Watch X-RateLimit-Remaining and slow down before it reaches zero, rather than waiting for the rejection.
  • Spread bursty work out. A backlog of 100 posts should be paced, not fired at once.
  • Use separate tokens for separate workloads. The api bucket is per token, so a one-off backfill script on its own token won't starve your production integration.