# Rate limits, errors and retries
URL: https://skedcast.com/developers/guides/social-media-api-rate-limits

Your plan sets a request budget per minute, for each API key or OAuth app and once more for the whole workspace. Every response carries the headers you need to back off correctly. Read them instead of guessing at a fixed delay.

## Rate limit headers
Header | Meaning
`RateLimit-Limit` | Your total budget for the current window
`RateLimit-Remaining` | What's left in the current window
`RateLimit-Reset` | Seconds until the window resets
`Retry-After` | On a 429 only: seconds to wait before retrying

## How usage is charged
Each request costs one unit, with these exceptions:
- A batch request (`POST /v1/posts/bulk` with N items) costs N units.
- A bulk action on targets costs one unit per destination it touches. Canceling 500 post targets in one call costs 500 units.
- A call the token's scope or role doesn't allow costs one unit, whatever the batch size, so a read-only token can't use up the budget other tokens share.

## Rate limits, errors and retries
The MCP server has its own budget per connected client, and destructive tools (delete, cancel, bulk cancel) get a tighter share of it. The API and MCP budgets are separate: a cap on one doesn't throttle the other.

## A 429 response.
```json
{
  "type": "https://skedcast.com/errors/rate_limited",
  "title": "Too many requests",
  "status": 429,
  "category": "rate-limit",
  "code": "rate_limited",
  "detail": "You are going too fast. Please slow down and try again.",
  "correlationId": "c-…"
}
```

## Retrying correctly
Every mutating request carries an Idempotency-Key, so a retry never creates a duplicate post. Retry a 429, 502, 503 or 504, or a request that got no response, with the same Idempotency-Key: SkedCast runs it once or returns the first result. Every other answer, including a 500, is kept for 24 hours and returned again for that key, so send a new key to try again. On a 429, wait for `Retry-After` instead of retrying immediately. A refused request still counts toward your budget, so hammering makes recovery slower, not faster.
- 400 / 422: fix the request. Retrying it unchanged fails the same way.
- 401: check the Authorization header and whether the key or token is still valid.
- 403: the token's scope or the owning member's role doesn't allow this action.
- 409: a state conflict, or a request with the same Idempotency-Key still running (`idempotency_in_progress`, wait for `Retry-After`). Inspect before retrying.
- 422 `idempotency_key_reuse`: the key was already used with a different body. Use a new key.
- 429: wait for Retry-After. `429 platform_capacity_exhausted` and `429 youtube_units_exhausted` mean a platform is temporarily at its limit. Retry after the wait in `Retry-After`.
- 502, 503 or 504: transient. Retry with backoff and the same Idempotency-Key. 500: the answer is kept for that key, so retry with a new key.

## FAQ
**Q: Does a rate-limited request against MCP affect my REST API budget?**
A: No. The REST API and the MCP server have separate budgets for the same client, so hitting one limit doesn't throttle the other.

**Q: Can I raise my rate limit without upgrading my plan?**
A: No. The per-minute budget is set by your plan. In Settings → Developer you can set a lower write limit on a key or a connected app. You cannot raise it above your plan's budget.
