# Limites de uso (rate limit)

> Entenda quantas chamadas a API do GS Engage aceita por minuto e como tratar o erro 429 com backoff para não travar sua integração.

- URL canônica: https://docs.growthstation.app/docs/api/conceitos/limites-de-uso
- Idioma: pt-BR
- Última atualização: 2026-09-20T08:21:20.450Z
- Produto: GS Engage
- Mantido por: Produto GS Engage



<PageHero emoji="🚦" title="Limites de uso (rate limit)" description="Quantas chamadas cabem por minuto, o que acontece quando você passa do limite e como se recuperar com elegância." gradient="amber" />

Toda integração saudável faz pausas. O GS Engage limita quantas chamadas você pode fazer por minuto para proteger a estabilidade da plataforma para todo mundo — inclusive para você. Esse teto é o que chamamos de **rate limit** (limite de requisições por período).

A boa notícia: respeitar o limite é simples. Se você seguir as práticas desta página, sua integração quase nunca vai esbarrar nele — e, quando esbarrar, vai se recuperar sozinha.

<Callout type="info" title="Requisição, leitura e escrita">
  Cada chamada à API é uma **requisição**. Uma **leitura** apenas consulta dados (métodos `GET` e `HEAD`). Uma **escrita** cria, altera ou remove dados (`POST`, `PUT`, `PATCH`, `DELETE`). Os limites são contados separadamente para leitura e escrita.
</Callout>

📊 Quais são os limites [#-quais-são-os-limites]

A janela é **fixa de 60 segundos**. A cada novo minuto, a contagem zera.

| Tipo de operação | Métodos HTTP                     | Limite          | Janela      |
| ---------------- | -------------------------------- | --------------- | ----------- |
| Leitura          | `GET`, `HEAD`                    | 200 requisições | 60 segundos |
| Escrita          | `POST`, `PUT`, `PATCH`, `DELETE` | 100 requisições | 60 segundos |

Na prática, isso é bastante folga para o dia a dia. Listar cadências, buscar leads e acompanhar prospecções cabe com sobra nas 200 leituras por minuto. As 100 escritas por minuto cobrem criação de leads em lote, notas e finalização de prospecções sem apertar.

<Callout type="tip" title="Sem ambiente de teste separado">
  Lembre-se: não existe sandbox no GS Engage. Toda chamada é real e conta para o limite. Ao experimentar, prefira operações de leitura — elas são mais generosas (200/min) e não alteram nada.
</Callout>

⛔ O que acontece quando você passa do limite [#-o-que-acontece-quando-você-passa-do-limite]

Se você ultrapassar o teto dentro da janela de 60 segundos, a próxima chamada não é atendida: a API responde com o status **HTTP 429** (Too Many Requests, ou "requisições demais").

Junto com o 429 vem o header **`Retry-After`**, que diz **em quantos segundos** você pode tentar de novo. Ele é a informação mais importante da resposta — é a própria API te dizendo o tempo exato de espera.

```bash
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 12
```

Essa resposta significa, em português: "você atingiu o limite; espere 12 segundos e siga em frente". Não é um erro da sua chave nem dos seus dados — é só um pedido de pausa.

<Callout type="warning" title="Não insista imediatamente">
  Repetir a chamada na hora, sem esperar, só piora a situação: você continua recebendo 429 e adia ainda mais a volta ao normal. Espere o tempo indicado no `Retry-After`.
</Callout>

📋 Os headers de controle [#-os-headers-de-controle]

Toda resposta traz headers que mostram sua situação atual em relação ao limite. Vale a pena lê-los para se antecipar, sem precisar esperar o 429 chegar.

| Header                  | O que informa                                                                             |
| ----------------------- | ----------------------------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | O teto total de requisições na janela atual (ex.: `200` para leitura).                    |
| `X-RateLimit-Remaining` | Quantas requisições ainda restam na janela atual. Quando chega a `0`, a próxima vira 429. |
| `X-RateLimit-Reset`     | Em quantos segundos a janela reinicia e a contagem volta ao topo.                         |
| `Retry-After`           | Aparece **só no 429**: quantos segundos esperar antes de tentar de novo.                  |

Uma leitura útil: se o `X-RateLimit-Remaining` está caindo rápido e chegando perto de `0`, é hora de reduzir o ritmo — não de acelerar.

🔁 Backoff exponencial, na prática [#-backoff-exponencial-na-prática]

**Backoff** é a técnica de aumentar a espera a cada nova tentativa, em vez de insistir no mesmo intervalo. **Backoff exponencial** dobra o tempo a cada tentativa (1s, 2s, 4s, 8s...), dando à API espaço para respirar.

A regra de ouro é simples: **se a resposta trouxer `Retry-After`, respeite esse valor.** Ele é preciso. Use o backoff exponencial apenas como plano B, quando o header não estiver disponível.

<Mermaid
  chart={`graph TD
A["Faz a requisição"] --> B{"Resposta 429?"}
B -->|Não| C["Segue o fluxo normal"]
B -->|Sim| D{"Tem Retry-After?"}
D -->|Sim| E["Espera os segundos indicados"]
D -->|Não| F["Espera com backoff exponencial (1s, 2s, 4s...)"]
E --> G["Tenta de novo"]
F --> G`}
/>

💻 Exemplo de tratamento do 429 [#-exemplo-de-tratamento-do-429]

O gatilho abaixo é comum: você faz uma chamada e, se levar um 429, espera o tempo certo e tenta de novo automaticamente.

<Tabs items={['JavaScript', 'Python']}>
  <Tab value="JavaScript">
    ```js
    async function chamarComRetry(url, options = {}, tentativas = 5) {
      for (let i = 0; i < tentativas; i++) {
        const resp = await fetch(url, options);

        if (resp.status !== 429) {
          return resp; // deu certo (ou é outro erro que você trata separado)
        }

        // Respeita o Retry-After; se não vier, faz backoff exponencial.
        const retryAfter = Number(resp.headers.get("Retry-After"));
        const esperaSegundos = retryAfter || Math.pow(2, i);

        console.log(`Rate limit atingido. Aguardando ${esperaSegundos}s...`);
        await new Promise((r) => setTimeout(r, esperaSegundos * 1000));
      }

      throw new Error("Limite de tentativas esgotado após vários 429.");
    }

    // Uso: a apiKey vai como query param na URL
    const resp = await chamarComRetry(
      "https://api.gsengage.com/api/v1/leads?apiKey=SUA_CHAVE"
    );
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import time
    import requests

    def chamar_com_retry(url, tentativas=5, **kwargs):
        for i in range(tentativas):
            resp = requests.get(url, **kwargs)

            if resp.status_code != 429:
                return resp  # deu certo (ou é outro erro que você trata separado)

            # Respeita o Retry-After; se não vier, faz backoff exponencial.
            retry_after = resp.headers.get("Retry-After")
            espera = int(retry_after) if retry_after else 2 ** i

            print(f"Rate limit atingido. Aguardando {espera}s...")
            time.sleep(espera)

        raise RuntimeError("Limite de tentativas esgotado após vários 429.")

    # Uso: a apiKey vai como query param na URL
    resp = chamar_com_retry(
        "https://api.gsengage.com/api/v1/leads?apiKey=SUA_CHAVE"
    )
    ```
  </Tab>
</Tabs>

Quando esse trecho retorna sem erro, significa que a chamada passou dentro do limite e seus dados chegaram — a espera aconteceu de forma transparente, sem você perder a requisição.

✅ Boas práticas para nunca travar [#-boas-práticas-para-nunca-travar]

Antes de considerar sua integração pronta, passe por esta lista. Ela evita a maioria dos 429 antes que eles aconteçam.

<Checklist id="rate-limit-boas-praticas" title="Checklist de rate limit">
  <ChecklistItem>
    Meu código lê o header 

    <TextHighlight>Retry-After</TextHighlight>

     no 429 e espera exatamente o tempo indicado?
  </ChecklistItem>

  <ChecklistItem>
    Tenho 

    <TextHighlight>backoff exponencial</TextHighlight>

     como plano B, para quando o 

    <code>Retry-After</code>

     não vier?
  </ChecklistItem>

  <ChecklistItem>
    Evito chamadas desnecessárias — não fico consultando o mesmo dado em loop nem repetindo requisições idênticas?
  </ChecklistItem>

  <ChecklistItem>
    Uso 

    <TextHighlight>paginação com <code>limit</code> maior</TextHighlight>

     para trazer mais itens por página e fazer menos chamadas no total?
  </ChecklistItem>

  <ChecklistItem>
    Prefiro leituras a escritas ao testar, já que o limite de leitura é maior (200/min)?
  </ChecklistItem>

  <ChecklistItem>
    Acompanho o 

    <TextHighlight>X-RateLimit-Remaining</TextHighlight>

     para desacelerar antes de chegar a zero?
  </ChecklistItem>
</Checklist>

<DoDont>
  <DoDontItem type="do">
    Respeitar o 

    <code>Retry-After</code>

    : ele é a espera exata que a própria API recomenda.
  </DoDontItem>

  <DoDontItem type="dont">
    Repetir a chamada imediatamente após um 429 — isso só prolonga o bloqueio.
  </DoDontItem>

  <DoDontItem type="do">
    Paginar com um 

    <code>limit</code>

     maior para percorrer listas grandes em menos requisições.
  </DoDontItem>

  <DoDontItem type="dont">
    Buscar página por página com 

    <code>limit</code>

     pequeno quando você poderia trazer muito mais de uma vez.
  </DoDontItem>

  <DoDontItem type="do">
    Guardar em cache dados que mudam pouco (como os campos personalizados) e reconsultar só quando necessário.
  </DoDontItem>

  <DoDontItem type="dont">
    Consultar o mesmo recurso repetidamente em um loop apertado.
  </DoDontItem>
</DoDont>

<Callout type="tip" title="Menos chamadas com paginação">
  Ao listar leads, prospecções ou conversas, use os parâmetros <code>limit</code> e <code>page</code>. Aumentar o <code>limit</code> traz mais itens por resposta e reduz o número de requisições — cada página economizada é uma chamada que não conta para o seu limite. Veja os detalhes em [Paginação e ordenação](/docs/api/conceitos/paginacao-filtros-ordenacao).
</Callout>

❓ Perguntas frequentes [#-perguntas-frequentes]

<FAQ>
  <FAQItem question="Leitura e escrita compartilham o mesmo limite?">
    Não. São contadores separados: 200 leituras por minuto e 100 escritas por minuto. Gastar suas leituras não consome suas escritas, e vice-versa.
  </FAQItem>

  <FAQItem question="A janela é deslizante ou fixa?">
    É fixa de 60 segundos. A cada novo minuto, a contagem reinicia do zero. O header <code>X-RateLimit-Reset</code> diz em quantos segundos isso acontece.
  </FAQItem>

  <FAQItem question="Recebi um 429. Fiz algo errado?">
    Não. O 429 não é um erro da sua chave nem dos seus dados — é apenas um pedido para desacelerar. Espere o tempo do <code>Retry-After</code> e continue normalmente.
  </FAQItem>

  <FAQItem question="Uso Zapier, Make ou n8n. Preciso me preocupar com isso?">
    Menos, porque essas ferramentas costumam repetir chamadas com espera automaticamente. Ainda assim, evite disparar volumes altos em rajada e prefira agendar execuções espaçadas.
  </FAQItem>
</FAQ>

Artigos Relacionados [#artigos-relacionados]

<RelatedArticles>
  <RelatedArticle href="/docs/api/conceitos/paginacao-filtros-ordenacao" title="Paginação e ordenação" description="Use limit e page para listar grandes volumes com menos chamadas." />

  <RelatedArticle href="/docs/api/conceitos/respostas-e-erros" title="Erros e status HTTP" description="Entenda 400, 401, 404 e 429 e como reagir a cada um." />

  <RelatedArticle href="/docs/api/comece-aqui/quickstart" title="Primeiros passos" description="Crie sua apiKey e valide a conexão com a API." />
</RelatedArticles>
