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

# Swytcho API Rate Limits: Tiers, Headers, and Retries

> Understand Swytcho's rate limit tiers, read the limit headers in every response, handle 429 errors gracefully, and learn how to request a quota increase.

Swytcho enforces rate limits to ensure fair, stable access to the API for all users. Limits are applied per API key and reset on a rolling window. Staying within your plan's limits — and handling the rare case when you exceed them — keeps your integration reliable under production load.

## Rate Limit Tiers

Limits are set by plan and measured along two axes: **requests per minute (RPM)** and **tokens per minute (TPM)**.

| Plan           | Requests / min | Tokens / min  | Notes                                            |
| -------------- | -------------- | ------------- | ------------------------------------------------ |
| **Free**       | 20 RPM         | 40 000 TPM    | Suitable for prototyping and personal projects   |
| **Starter**    | 200 RPM        | 400 000 TPM   | Suitable for early-stage production applications |
| **Pro**        | 1 000 RPM      | 2 000 000 TPM | Suitable for scaled production workloads         |
| **Enterprise** | Custom         | Custom        | Contact sales for dedicated capacity and SLA     |

<Info>
  Embedding requests (`/v1/embeddings`) and chat completion requests each count against the same per-key RPM and TPM limits. Plan your total API traffic budget accordingly.
</Info>

## Rate Limit Headers

Swytcho includes rate limit metadata in the HTTP response headers of **every** API call — not just when you are close to the limit. Read these headers proactively to throttle your requests before hitting the ceiling.

| Header                  | Description                                                                    |
| ----------------------- | ------------------------------------------------------------------------------ |
| `X-RateLimit-Limit`     | Your plan's maximum allowed requests in the current window                     |
| `X-RateLimit-Remaining` | Requests remaining before you hit the limit                                    |
| `X-RateLimit-Reset`     | Unix timestamp (seconds) when the current window resets and your quota refills |

### Example Response Headers

```http theme={null}
HTTP/2 200 OK
Content-Type: application/json
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1713042060
```

Use `X-RateLimit-Remaining` and `X-RateLimit-Reset` together to calculate how long to pause before your next request if you are approaching the limit.

## When You Hit a Rate Limit

When you exceed your plan's RPM or TPM limit, the API responds with an HTTP `429 Too Many Requests` status and a `Retry-After` header that tells you exactly how many seconds to wait before retrying.

```http theme={null}
HTTP/2 429 Too Many Requests
Content-Type: application/json
Retry-After: 12
```

```json theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "You have exceeded your requests-per-minute limit. Please retry after 12 seconds.",
    "param": null
  }
}
```

<Warning>
  Never silently swallow or ignore `429` responses. Continuing to send requests after receiving a `429` without backing off will extend the time before your quota resets and may trigger temporary key suspension under Swytcho's abuse prevention policy. Always implement a retry strategy.
</Warning>

## Best Practices

### Exponential Backoff

Implement exponential backoff with jitter to spread retry attempts and avoid synchronized bursts from multiple workers all retrying at the same moment.

<CodeGroup>
  ```python Python theme={null}
  import time
  import random
  import httpx

  def call_with_backoff(payload: dict, max_retries: int = 6) -> dict:
      base_delay = 1.0  # seconds

      for attempt in range(max_retries):
          response = httpx.post(
              "https://api.swytcho.com/v1/chat/completions",
              headers={
                  "Authorization": f"Bearer {SWYTCHO_API_KEY}",
                  "Content-Type": "application/json",
              },
              json=payload,
              timeout=120,
          )

          if response.status_code == 429:
              retry_after = float(response.headers.get("Retry-After", base_delay * (2 ** attempt)))
              jitter = random.uniform(0, retry_after * 0.1)
              wait = retry_after + jitter
              print(f"Rate limited. Retrying in {wait:.1f}s (attempt {attempt + 1}/{max_retries})")
              time.sleep(wait)
              continue

          response.raise_for_status()
          return response.json()

      raise RuntimeError("Max retries exceeded after repeated 429 responses.")
  ```

  ```typescript TypeScript theme={null}
  async function callWithBackoff(payload: object, maxRetries = 6): Promise<Response> {
    const baseDelay = 1000; // milliseconds

    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await fetch("https://api.swytcho.com/v1/chat/completions", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.SWYTCHO_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify(payload),
      });

      if (response.status === 429) {
        const retryAfter = parseFloat(response.headers.get("Retry-After") ?? "1");
        const jitter = Math.random() * retryAfter * 0.1;
        const wait = (retryAfter + jitter) * 1000;
        console.log(`Rate limited. Retrying in ${(wait / 1000).toFixed(1)}s (attempt ${attempt + 1}/${maxRetries})`);
        await new Promise((resolve) => setTimeout(resolve, wait));
        continue;
      }

      return response;
    }

    throw new Error("Max retries exceeded after repeated 429 responses.");
  }
  ```
</CodeGroup>

### Request Queuing

For high-throughput workloads, maintain a local request queue and a token bucket counter that mirrors `X-RateLimit-Remaining`. Dispatch requests from the queue only when you have remaining capacity. This smooths your traffic and prevents burst spikes that would trigger a `429`.

<Tip>
  If you are running multiple service instances, centralise your rate limit state in a shared store so all instances share the same token bucket. Per-instance counters lead to over-dispatching and avoidable `429` errors.
</Tip>

## Request a Rate Limit Increase

If your application consistently requires more capacity than your plan provides, you can request a higher limit:

<Steps>
  <Step title="Open the Swytcho Dashboard">
    Navigate to **Settings → Usage & Limits** in the [Swytcho Dashboard](https://dashboard.swytcho.com).
  </Step>

  <Step title="Submit a limit increase request">
    Click **Request Increase**, select the limit type (RPM or TPM), enter your required value, and describe your use case. Include traffic projections if available.
  </Step>

  <Step title="Wait for review">
    The Swytcho team reviews limit increase requests within **2 business days**. You will receive an email confirmation when the new limit is active on your key.
  </Step>

  <Step title="Consider upgrading your plan">
    If you need a sustained high throughput, upgrading to the **Pro** or **Enterprise** plan is faster than a manual increase request and includes dedicated support. Visit the [Pricing page](https://swytcho.com/pricing) for details.
  </Step>
</Steps>
