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

# Mitigate Errors

> Identify and handle Finch API responses and errors — null values, 202 responses, server errors, reauthentication errors, and rate limit errors — with mitigation steps for each.

This guide covers the responses and errors developers most frequently encounter with the Finch API. Null values and 202 responses are expected parts of a normal response — but your application can misbehave if it doesn't handle them. Server errors, reauthentication errors, and rate limit errors are true error conditions Finch returns when something goes wrong. Your application should expect and handle the [error types](/api-reference/development-guides/errors/Error-Types) documented in the API reference.

## Null values

A `null` value isn't an error — it's an expected response value. See [Null Values](/api-reference/development-guides/Handling-API-Responses#null-values) for why Finch returns `null` and how to check for it.

## 202 responses

A `202` response isn't an error either — it means the connection exists but data isn't available yet. See [202 Response Codes](/api-reference/development-guides/Handling-API-Responses#202-response-codes) for the retry and backoff behavior your application should implement, or [Testing assisted integrations](/implementation-guide/Test/Finch-Sandbox#testing-assisted-integrations) to reproduce a `202` response in the Finch Sandbox.

## Server errors

Server errors (`HTTP 500`) are uncommon but possible. A few error-handling mechanisms help you maintain a good user experience while diagnosing the issue:

* **Friendly error page.** Display a user-friendly message instead of the raw server error to maintain user trust.
* **Log the error.** Capture the error message, stack trace, request details, and other relevant context. Always log the `finch-request-id` from the HTTP response headers — Finch needs it to diagnose the issue on our side.
* **Health checks.** Call the [/introspect](/api-reference/management/introspect) endpoint on a regular basis to monitor the status of your Finch integration and its connections — this helps you identify the source of `500` errors faster.
* **Retry.** Retry the request after a delay, or adjust the request parameters — this resolves many transient server errors.

<Warning>
  **Product outages.** Finch reports all API outages and provider integration incidents at [status.tryfinch.com](https://status.tryfinch.com) — subscribe there for email notifications when Finch creates, updates, or resolves an incident.
</Warning>

If a server error persists, contact [Finch Support](/implementation-guide/Deploy-and-Manage/Support) and attach the `finch-request-id` from the response headers.

### Retry example

Finch may also return `4XX` or `5XX` [error types](/api-reference/development-guides/errors/Error-Types) due to unsupported responses from the underlying employment system. Retrying immediately may not resolve the issue — the following example retries a failed request with a fixed delay:

```jsx Error handling example theme={null}
function fetchDataWithRetry(url, options, retries = 3, delay = 2000) {
  return fetch(url, options)
    .then(response => {
      if (response.status === 500 && retries > 0) {
        return new Promise(resolve => setTimeout(resolve, delay))
          .then(() => fetchDataWithRetry(url, options, retries - 1, delay));
      } else {
        return response;
      }
    })
    .catch(error => console.error('Error:', error));
}

fetchDataWithRetry(url, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
})
.then(response => response.json())
.then(data => console.log(data));
```

## Reauthentication errors

A reauthentication error means the credentials Finch uses to access an employer's provider system no longer work, and the employer must reauthenticate. This returns an HTTP status code of `401 Unauthorized` with a `finch_code` of `reauthenticate_user` (see [Finch API errors](/api-reference/development-guides/errors/Error-Types)).

To handle this error:

1. Catch `401` responses with a `finch_code` of `reauthenticate_user` in your Finch API error handling.
2. Create a new Finch Connect session for the connection using the [`/connect/sessions/reauthenticate`](/api-reference/connect/reauthenticate-session) endpoint, passing the connection's `connection_id`. If your application doesn't already store the `connection_id`, retrieve it by calling [/introspect](/api-reference/management/introspect) with the connection's `access_token`.
3. Direct the employer to complete Finch Connect through your existing flow — for example, prompt them to log in to your application dashboard, or send them a link to reauthenticate.
4. Exchange the resulting authorization code for a new access token — this is the same [access token exchange](/implementation-guide/Connect/Retrieve-Access-Token) used during initial setup.

See [Reauthentication](/developer-resources/Reauthentication) for what causes this error and how to handle multi-entity connections, employee permissions, and product scopes when reauthenticating.

## Rate limit errors

Finch returns a rate limit error with the HTTP status code `429 Too Many Requests` when an application or IP address exceeds its request limit. Review the API [rate limits](/api-reference/development-guides/Rate-Limits) before continuing.

Finch's [rate limits](/api-reference/development-guides/Rate-Limits) work on a per-endpoint basis for applications. Finch calls each distinct endpoint a unique product, and sums rate limits on a rolling 60-second basis per product — commonly called a sliding or rolling window rate limit.

Think of each product's rate limit as a bucket. Every request to a product (which maps to an API endpoint) adds a gallon of water to that endpoint's bucket and starts a 60-second time-to-live (TTL) timer. When the bucket empties after 60 seconds, the next request restarts the TTL.

Stay within these [rate limits](/api-reference/development-guides/Rate-Limits) to avoid request failures. If you hit a rate limit error, implement a [back-off and retry strategy](#rate-limit-example): wait 60 seconds for the bucket to reset, then retry, increasing the wait time exponentially on repeated failures.

### Batch requests

[Batch requests](/implementation-guide/API-Calls/Batch-Requests) instead of calling an endpoint once per ID, to reduce your request count and avoid exhausting your rate limit.

### Rate Limit Scenario

This scenario shows how an application encounters application-level [rate limits](/api-reference/development-guides/Rate-Limits). Assume your application has five access tokens (Token A–E) making requests to the `company`, `directory`, `individual`, `employment`, `payment`, and `pay-statement` endpoints.

Each request to an endpoint adds a gallon of water to that product's application-level bucket. The bucket counts requests across all of the application's access tokens (Token A–E).

Organization endpoints have a [capacity](/api-reference/development-guides/Rate-Limits) of 20 max requests per minute. Pay endpoints have a [capacity](/api-reference/development-guides/Rate-Limits) of 12 max requests per minute.

<Warning>Each step below happens within the same 60-second (1-minute) time window.</Warning>

1. Token A makes 5 requests to [/company](/api-reference/organization/company), 4 to [/directory](/api-reference/organization/directory), and 3 to [/payment](/api-reference/payroll/payment) within a minute. Each bucket is below its capacity, so all of Token A's requests succeed.
   * Application-level rate limits
     | Bucket          | Capacity       |
     | --------------- | -------------- |
     | `company`       | 5/20 - success |
     | `directory`     | 4/20 - success |
     | `individual`    | 0/20           |
     | `employment`    | 0/20           |
     | `payment`       | 3/12 - success |
     | `pay-statement` | 0/12           |
2. Token B makes 5 more requests to [/company](/api-reference/organization/company), 4 to [/directory](/api-reference/organization/directory), and 3 to [/payment](/api-reference/payroll/payment) within the same minute. Each bucket is still below capacity, so all of Token B's requests succeed.
   * Application-level rate limits
     | Bucket          | Capacity        |
     | --------------- | --------------- |
     | `company`       | 10/20 - success |
     | `directory`     | 8/20 - success  |
     | `individual`    | 0/20            |
     | `employment`    | 0/20            |
     | `payment`       | 6/12 - success  |
     | `pay-statement` | 0/12            |
3. Tokens C and D each repeat the same pattern — 5 requests to [/company](/api-reference/organization/company), 4 to [/directory](/api-reference/organization/directory), and 3 to [/payment](/api-reference/payroll/payment) — within the same minute. The `company` and `payment` buckets reach full capacity, but Token C's and D's requests still succeed because the limits haven't been exceeded yet.
   * Application-level rate limits
     | Bucket          | Capacity               |
     | --------------- | ---------------------- |
     | `company`       | 20/20 (FULL) - success |
     | `directory`     | 16/20 - success        |
     | `individual`    | 0/20                   |
     | `employment`    | 0/20                   |
     | `payment`       | 12/12 (FULL) - success |
     | `pay-statement` | 0/12                   |
4. Token E then makes 1 request to [/company](/api-reference/organization/company) and 1 to [/directory](/api-reference/organization/directory). The `company` and `payment` buckets are now full, so any further request to those endpoints — including Token E's `/company` request — returns a 429 rate limit error until the 60-second TTL resets. Token E's `/directory` request succeeds because that bucket isn't full yet. Only successful requests count toward the application-level limit.
   * Application-level rate limits
     | Bucket          | Capacity             |
     | --------------- | -------------------- |
     | `company`       | 20/20 (FULL) - error |
     | `directory`     | 16/20 - success      |
     | `individual`    | 0/20                 |
     | `employment`    | 0/20                 |
     | `payment`       | 12/12 (FULL) - error |
     | `pay-statement` | 0/12                 |

Every fifth request to [/company](/api-reference/organization/company) for each token fails with a 429 rate limit error once its bucket is full.

### Rate limit example

The following `RateLimiter` class enforces this quota at the application level. Initialized with a limit (for example, 20 requests per minute for [/directory](/api-reference/organization/directory)), it makes requests up to that limit and pauses further requests until the bucket resets after 60 seconds. Call its `request` method to make API requests through the rate limiter, and initialize a separate `RateLimiter` instance for each endpoint you call.

```js theme={null}
class RateLimiter {
  constructor(limit) {
    this.limit = limit;
    this.requests = [];
  }

  async request(fn) {
    const now = Date.now();
    this.requests = this.requests.filter((timestamp) => now - timestamp < 60000);

    if (this.requests.length >= this.limit) {
      const delay = this.requests[0] + 60000 - now;
      await new Promise((resolve) => setTimeout(resolve, delay));
      this.requests.shift();
    }

    this.requests.push(now);
    return fn();
  }
}

const directoryRateLimiter = new RateLimiter(20); // 20 requests per minute
const url = 'https://api.tryfinch.com/employer/directory'; // Replace with the desired endpoint
const accessToken = '<your_access_token>';

const fetchIndividualData = (
) =>
  fetch(url, {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
  });

// Use the rate limiter to make API requests
directoryRateLimiter
  .request(fetchIndividualData)
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error('Error:', error));
```

## Checkpoint + Next Step

<Check>
  Your application can now handle Finch's most common error scenarios, making your integration more resilient. Monitoring API requests makes error mitigation easier — see [Monitor API Usage](/implementation-guide/Backend-Application/Monitor-Usage) next.
</Check>

## Learn more

* [Handling API Responses](/api-reference/development-guides/Handling-API-Responses)
* [Set Up Finch Connect](/implementation-guide/Connect/Set-Up-Finch-Connect)
* [Rate Limits](/api-reference/development-guides/Rate-Limits)
* [Error Types](/api-reference/development-guides/errors/Error-Types)
