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

# Rate limits

> Understand Swish API rate limits and how to handle throttled requests.

The Swish API enforces rate limits to ensure fair usage and platform stability. When you exceed the limit, the API returns a `429 Too Many Requests` response.

## How it works

Each endpoint is subject to a **60-second sliding window**. If the number of requests from a single client exceeds the limit within that window, subsequent requests are throttled until the window resets.

Rate limits are tracked per authenticated user (store + profile). Unauthenticated requests are tracked by IP address.

## Rate limit groups

Endpoints are assigned to one of four groups based on their expected traffic pattern:

| Group | Limit | Window |
| - | - | - |
| Small | 30 requests | 60 s |
| Medium | 120 requests | 60 s |
| Large | 300 requests | 60 s |
| Extra large | 3,500 requests | 60 s |

### Endpoint assignments

> [accordion] Small
>
> * Orders (`GET /orders`, `GET /orders/{orderId}`)
> * Profile identify (`POST /profiles/identify`)

> [accordion] Medium (default)
>
> * Items (`GET /items`, `POST /items`, `PATCH /items/{itemId}`, `DELETE /items`, etc.)
> * Lists (`GET /lists`, `POST /lists`, `PATCH /lists/{listId}`, `DELETE /lists/{listId}`, etc.)
> * Shared lists (`GET /shared-lists`, `POST /shared-lists`, etc.)
> * Smart lists (`GET /smart-lists`, `DELETE /smart-lists/{smartListId}/items/{itemId}`, etc.)
> * Notifications (`GET /notifications`, `POST /notifications/read`, etc.)
> * Subscriptions (`GET /subscriptions`, `POST /subscriptions`, etc.)
> * Profile (`POST /profiles/token`, `GET /profiles`, `PATCH /profiles/profile`)

> [accordion] Extra large
>
> * Tracking (`POST /collect`)

> [!NOTE]
>
> The large group (300 req/60s) exists but is not currently assigned to any
> endpoint. It is reserved for future use.

## Rate limit headers

Successful responses include headers that report your current usage:

| Header | Description |
| - | - |
| `X-RateLimit-Limit` | Maximum number of requests allowed in the current window. |
| `X-RateLimit-Remaining` | Number of requests remaining in the current window. |
| `X-RateLimit-Reset` | Seconds remaining until the current window resets. |

When a request is throttled (`429`), the response includes a single header:

| Header | Description |
| - | - |
| `Retry-After` | Number of seconds to wait before retrying. |

## Handling 429 responses

When you hit the rate limit, the API returns a `429` status with a `Retry-After` header indicating how many seconds to wait before retrying.

```json theme={null}
{
  "error": {
    "message": "API rate limit exceeded",
    "error": "Too Many Requests",
    "statusCode": 429,
    "requestId": "123e4567-e89b-12d3-a456-426614174000"
  }
}
```

## Retry strategies

When you receive a `429`, wait for the number of seconds indicated by `Retry-After` before retrying.

```typescript @swishapp/api-client theme={null}
import { createApiClient } from "@swishapp/api-client/2026-07";

const client = createApiClient({
  authToken: "your-api-token",
  responseInterceptor: async (response, request) => {
    if (response.status === 429) {
      const resetAfter = Number(response.headers.get("Retry-After") || 60);
      await new Promise((resolve) => setTimeout(resolve, resetAfter * 1000));
      return fetch(request);
    }
    return response;
  },
});
```

```typescript JavaScript theme={null}
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status !== 429) {
      return response;
    }

    if (attempt === maxRetries) {
      return response;
    }

    const resetAfter = Number(response.headers.get("Retry-After") || 60);
    await new Promise((resolve) => setTimeout(resolve, resetAfter * 1000));
  }
}

const response = await fetchWithRetry("https://swish.app/api/2026-07/items", {
  headers: { Authorization: "Bearer your-api-token" },
});
```

```bash cURL theme={null}
# A 429 response includes a Retry-After header
curl -i https://swish.app/api/2026-07/items \
  -H "Authorization: Bearer your-api-token"

# HTTP/1.1 429 Too Many Requests
# Retry-After: 45
```

> [!TIP]
>
> The `@swishapp/api-client` supports request and response interceptors, making
> it straightforward to add retry logic in one place rather than wrapping every
> call.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.