# Understanding and Resolving Race Conditions in API Requests

Firing multiple concurrent requests through an OAuth connector (like [Xero](/apis/accounting/xero) or
[Salesforce](/apis/crm/salesforce)) whose access token is about to expire can trigger several simultaneous
token refreshes, leaving different requests using different token versions and some failing validation.
Fix it by calling Vault's `validateConnectionState` endpoint once to force a single refresh before starting
the batch of concurrent requests, so every request uses the same valid token.

![](/guides/refresh-token-race-condition.png)

## What is a Token Refresh Race Condition?

A token refresh race condition happens when several concurrent API requests each independently notice that
an OAuth access token is about to expire and each try to refresh it at the same time, instead of one request
refreshing it on behalf of all of them.

## The Problem

Concretely, this is the sequence: your application makes multiple concurrent API requests, each one
independently checks whether the token is about to expire, and each one that sees an expiring token tries to
refresh it. That produces multiple simultaneous refresh operations, so different requests can end up holding
different token versions, and some of them fail token validation as a result.

## Why This Causes Problems

Multiple simultaneous refreshes mean different requests can be using different token versions at the same
moment. Requests holding a token version the downstream API no longer considers current fail validation, and
the overall connection can behave inconsistently until the refreshes settle.

## What does this mean in the Apideck context?

Apideck checks whether a connection's access token will expire within 30 seconds before processing each
request, and refreshes it first if so. When several requests arrive concurrently, each one runs this check
independently, so an expiring token can trigger several simultaneous refresh operations, the same race
condition described above.

## Visual Representation

```
Request 1 ──> Checks token ──> Refreshes token ──> Uses new token A ──> Success
                    │
Request 2 ──> Checks token ──> Refreshes token ──> Uses new token B ──> Success/Failure?
                    │
Request 3 ──> Checks token ──> Refreshes token ──> Uses new token C ──> Success/Failure?
```

## The Solution

Validate the connection and refresh its token once, before making any concurrent requests, so every request
in the batch reuses that single valid token instead of triggering its own refresh:

```
                                                  ┌──> Request 1 ──> Uses token X ──> Success
                                                  │
Validate connection ──> Refresh token once ──────┼──> Request 2 ──> Uses token X ──> Success
                                                  │
                                                  └──> Request 3 ──> Uses token X ──> Success
```

## Implementation Steps

Call the Vault API's [validateConnectionState](https://developers.apideck.com/apis/vault/reference#tag/Connections/operation/validateConnectionState)
endpoint first: it forces a refresh of the connection's access token and returns a 200 status code on
success. Only start your batch of concurrent requests after you receive that successful response.

## Best Practices

Validate the connection before starting any batch of concurrent requests, and add retry logic with
exponential backoff for requests that still fail, since a downstream API can throttle or error independently
of the token race condition described above.
