> ## Documentation Index
> Fetch the complete documentation index at: https://www.finta.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage Limits

> Rate limits, monthly call limits, and how they are enforced

The Finta API enforces two independent limits. Both surface as `429 Too Many Requests`, but they are distinct error codes with different retry guidance. Branch on `error.code` to tell them apart.

## Per-minute burst limit

Authenticated requests are limited to **6,000 requests per 60 seconds** (100 per second) per API key. Unauthenticated requests (missing or invalid key) are limited to **120 requests per 60 seconds** per IP address.

The window is **fixed**, not rolling. Each 60-second wall-clock interval is its own counter; all requests within that interval share it, and the counter resets to 0 in a single step at the next boundary. Available budget jumps from `0` back to the full bucket size (`6000` for authenticated API keys, `120` for unauthenticated IP buckets) instantaneously at the boundary, rather than aging out one slot at a time. Trust `X-RateLimit-Reset` for the exact reset timestamp; do not assume requests age out individually.

### Headers

Every authenticated response (including non-429s) includes three headers so you can monitor consumption:

| Header                  | Type    | Meaning                                                                                                                            |
| ----------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | integer | Total budget for the current window. `6000` for authenticated requests (per API key), `120` for unauthenticated requests (per IP). |
| `X-RateLimit-Remaining` | integer | Requests remaining in the current window. Reaches `0` immediately before a burst-limit 429.                                        |
| `X-RateLimit-Reset`     | integer | Unix timestamp (seconds) when the window resets and `X-RateLimit-Remaining` returns to its full budget.                            |

A 429 in this case adds one more header:

| Header        | Type              | Meaning                                                                                                                                                     |
| ------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Retry-After` | integer (seconds) | Minimum number of seconds to wait before the next request. Range in practice: 1 to 60, since the burst window is 60 seconds. Do not retry sooner than this. |

### Example error body

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-RateLimit-Limit: 6000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1714434660
Content-Type: application/json

{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please retry after the Retry-After period.",
    "doc_url": "https://www.finta.com/docs/api-reference/errors#rate_limit_exceeded"
  }
}
```

### Retry guidance

This 429 is **retryable**. Recommended pattern:

1. Honor `Retry-After` as the minimum wait. Do not retry sooner.
2. For retries beyond the first, apply exponential backoff with jitter (e.g. base = `Retry-After`, double on each attempt, add random jitter in `[0, 1s]`, cap at a few minutes).
3. Cap the total number of attempts (e.g. 3 to 5) and surface the failure if exhausted, rather than retrying indefinitely.
4. Treat `X-RateLimit-Remaining` as a leading indicator: if it is near zero on a successful response, slow down voluntarily before the next request to avoid the 429 entirely.

## Monthly per-company limit

Each company has a monthly cap on total API calls, independent of and in addition to the per-minute burst limit:

| Plan                 | Monthly cap |
| -------------------- | ----------- |
| Formation (free)     | 10          |
| Startup (\$30/month) | 300         |
| Growth (\$300/month) | 30,000      |

The limit is per company, not per API key. All keys for a company share the same pool.

Counts reset at **midnight Pacific Time (US & Canada)** on the 1st of each month. This is the Finta application's configured time zone; the cap is computed in that zone, not in UTC. Consumers in other time zones should convert that local-midnight Pacific boundary to their own clock. The absolute UTC offset shifts by one hour twice a year for daylight saving (PST is UTC-8, PDT is UTC-7), so consumers needing exact second-level precision near month boundaries should account for the active offset on the date in question.

**What counts:** all authenticated requests count toward the monthly cap, regardless of HTTP status. A `400` from bad parameters counts the same as a `200`. Unauthenticated requests (`401`) do not count, and blocked requests (after hitting the monthly limit) are also not counted, so hitting the cap does not extend the cap-exceeded period.

### Example error body

```http theme={null}
HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": {
    "type": "limit_error",
    "code": "monthly_limit_exceeded",
    "message": "Monthly API limit reached. Your plan allows 300 calls per company per month. Resets on May 1, 2026. Upgrade in Settings -> Plans at app.finta.com.",
    "doc_url": "https://www.finta.com/docs/api-reference/errors#monthly_limit_exceeded"
  }
}
```

`Retry-After` is **not** sent in this case. The `X-RateLimit-*` burst-window headers may still be present but are unrelated to the monthly cap.

### Retry guidance

This 429 is **not retryable in the short term.** The only meaningful remediation is to upgrade the plan or wait until the 1st of the next month. Recommended pattern:

1. Branch on `error.code` first. `rate_limit_exceeded` is the burst case (retryable, see above). `monthly_limit_exceeded` is this case.
2. If the code is `monthly_limit_exceeded`, **stop retrying.** Surface the error to your user with the reset date from the message body, or page the operator to upgrade the plan.
3. SDKs that auto-retry on 429 should treat the absence of `Retry-After` as a "do not retry" signal, or branch on `error.code` directly.

## Best practices

* **Branch on `error.code`, not the status code alone.** Both limits surface as 429 but have different remediation paths. A retry loop that does not distinguish the two will burn through quota on monthly exhaustion.
* **Check headers proactively.** Monitor `X-RateLimit-Remaining` and slow down before you hit the burst limit.
* **Use larger page sizes.** When paginating, set `limit` up to 500 to pull more data per request and reduce total calls.
* **Cache responses.** If you are repeatedly pulling the same data, cache it on your end to conserve your monthly quota.
