# Rate limits

> The RemakeCV API allows 30 requests per minute per company by default. Limits are returned in standard RateLimit headers and exceeding them returns 429.

Source: https://www.remakecv.com/help/api-reference/rate-limits
Last updated: 2026-08-21

---
The default rate limit is 30 requests per minute, counted per company rather than per API key. Limits are reported in standard `RateLimit` response headers, and exceeding one returns `429` with the code `rate_limit_exceeded`. The limit is configurable per company if your volume needs it raised.

## What is the limit?

| Property | Value |
|---|---|
| Default limit | 30 requests per minute |
| Window | 60 seconds |
| Scope | Per company |
| Configurable | Yes, per company |
| Headers | `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, `RateLimit-Policy`; `Retry-After` on a 429 |

> **Warning:** 
The limit is per company, not per key. If you run several integrations against the same RemakeCV account, they compete for the same 30 requests per minute. Adding keys does not add capacity.

### Reading the headers

`RateLimit-Reset` and `Retry-After` are both **seconds until the window resets**, not a timestamp. There are no `X-RateLimit-*` headers — only the unprefixed standard ones.

## What happens when I exceed it?

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded for this company.",
    "request_id": "b7c1e4a2-..."
  }
}
```

Returned with HTTP `429`. Nothing is processed, and no credit is consumed.

## How should I handle it?

Exponential backoff with jitter. The jitter matters: without it, several workers that hit the limit together will retry together and hit it again.

```javascript
async function callWithRetry(request, attempts = 5) {
  for (let attempt = 0; attempt < attempts; attempt += 1) {
    const response = await request();
    if (response.status !== 429) return response;

    // Prefer the server's own reset hint; fall back to exponential backoff.
    const reset = Number(response.headers.get('RateLimit-Reset'));
    const backoff = Number.isFinite(reset) && reset > 0
      ? reset * 1000
      : 2 ** attempt * 1000;

    await new Promise((r) => setTimeout(r, backoff + Math.random() * 500));
  }
  throw new Error('Rate limit retries exhausted');
}
```

## How do I process a large batch?

At 30 requests per minute, a 500-CV migration takes roughly 17 minutes of steady requests. Two things make that reliable:

### Pace deliberately, do not burst

Sending two requests per second and staying under the limit is faster overall than bursting, hitting `429`, and backing off.

### Make the job resumable

Track which CVs succeeded. A batch that fails at item 400 should restart at 400, not at 1 — reprocessing costs credits.

### Ask for a higher limit first

If you have a one-off migration, email support@remakecv.com. Raising the limit for the duration is easier than engineering around it — and it is not something you can change yourself, even as an administrator.

## Related

- [Errors and status codes](https://www.remakecv.com/help/api-reference/errors.md) — the full error contract
- [`POST /cvs/process`](https://www.remakecv.com/help/api-reference/endpoints/process-a-cv.md) — the endpoint you will call most
- [Process a CV and save the result](https://www.remakecv.com/help/api-reference/recipes/process-and-download.md) — a paced batch example

## Does a rate-limited request cost a credit?

No. A `429` is rejected before any processing happens.

## Frequently asked questions

### Is the limit per key or per company?

Per company. Issuing extra API keys does not increase your throughput — all keys for a company share the same budget.

### Can the limit be raised?

Yes, per company — but not self-serve. The field is shown read-only in Company Settings, so email support@remakecv.com with your expected volume.

### How should I handle a 429?

Back off and retry using exponential backoff with jitter. Read the RateLimit-Reset header to know when the window rolls over.
