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

# Usage limits

> Request limit per company on the Connecta DESK API: RateLimit headers, the 429 response and what to do when you reach the limit.

The API limits the number of requests **per company**, in fixed one-minute windows. All of the
company's tokens share the same limit, so creating a second token does not increase the number of
calls allowed.

<Info>
  The default is **120 requests per minute**. Companies that need more can have their own limit
  set in the plan. If your integration will need more than that, talk to sales before planning it
  around the default limit.
</Info>

## The headers

Every response reports the current state of the window. Rely on these headers instead of counting
requests on your side, because the count includes the company's other integrations.

<ResponseField name="RateLimit-Limit" type="integer">
  The company's request limit for the current minute.
</ResponseField>

<ResponseField name="RateLimit-Remaining" type="integer">
  How many requests still fit in the current window.
</ResponseField>

<ResponseField name="RateLimit-Reset" type="integer">
  Seconds until the window ends and the counter goes back to zero.
</ResponseField>

```bash theme={null}
RateLimit-Limit: 120
RateLimit-Remaining: 96
RateLimit-Reset: 34
```

## When the limit is reached

```json theme={null}
{
  "error": {
    "code": "ERR_API_RATE_LIMIT",
    "message": "Limite de requisições por minuto excedido para esta empresa."
  }
}
```

The response is `429` and includes one more header:

<ResponseField name="Retry-After" type="integer">
  Seconds to wait before trying again. It matches the time left until the window ends.
</ResponseField>

<Warning>
  Respect the `Retry-After`. If you repeat the call right away, you only use up the next window and
  the integration keeps getting `429`. The company's other integrations are affected too, because
  they share the same limit.
</Warning>

## How to handle the 429

<CodeGroup>
  ```javascript Node.js theme={null}
  async function call(path, init = {}, attempts = 4) {
    for (let i = 1; i <= attempts; i++) {
      const res = await fetch(`${process.env.CONNECTA_URL}${path}`, {
        ...init,
        headers: {
          Authorization: `Bearer ${process.env.CONNECTA_TOKEN}`,
          ...init.headers
        }
      });

      if (res.status !== 429) return res;

      // The server already says how long to wait; the jitter keeps several instances
      // from coming back at exactly the same instant and blowing the window again.
      const wait = Number(res.headers.get('Retry-After') ?? 60);
      await new Promise((r) => setTimeout(r, (wait + Math.random() * 2) * 1000));
    }

    throw new Error('Persistent rate limit');
  }
  ```

  ```python Python theme={null}
  import os, time, random, requests

  def call(path, attempts=4, **kwargs):
      for _ in range(attempts):
          res = requests.get(
              f"{os.environ['CONNECTA_URL']}{path}",
              headers={"Authorization": f"Bearer {os.environ['CONNECTA_TOKEN']}"},
              **kwargs,
          )

          if res.status_code != 429:
              return res

          wait = int(res.headers.get("Retry-After", 60))
          time.sleep(wait + random.uniform(0, 2))

      raise RuntimeError("Persistent rate limit")
  ```
</CodeGroup>

## How to stay away from the limit

<AccordionGroup>
  <Accordion title="Raise perPage before raising the frequency" icon="list">
    Reading a list with `perPage=100` costs 1 request every 100 records. With the default of 20,
    it costs 5. This is the adjustment that cuts usage the most, and it is also the easiest to
    make. See [Pagination](/en/essentials/paginacao).
  </Accordion>

  <Accordion title="Avoid checking too often" icon="timer">
    Checking `GET /messages/jobs/{jobId}` every 200 ms uses up the whole window in a little over
    20 seconds. Start with 1-second intervals and increase them gradually.
  </Accordion>

  <Accordion title="Keep what does not change" icon="database">
    Queues, tags, wrap-up types, channels and custom fields rarely change. Fetching these lists on
    every operation is the most common waste. Read them once and keep a copy on your side.
  </Accordion>

  <Accordion title="Spread out the routines" icon="clock">
    If three integrations run a full load at midnight, they compete for the same limit. Spread the
    schedules out.
  </Accordion>
</AccordionGroup>

## Sending messages and the limit

`POST /messages` responds `202` right away and sends in the background. The request counts toward
the limit, but the send itself does not. How fast messages go out depends on the channel's
provider.

<Note>
  You can queue 120 messages in a minute, but they will not all go out in that same minute. For
  high-volume sends, use [campaigns](/en/api-reference/introduction) instead of a loop over
  `POST /messages`. A campaign is built for that pace and lets you pause, resume and follow the
  send in the report.
</Note>


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