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

# Rate limits

> A Ticto API v2 permite 120 leituras e 30 escritas por minuto, por token. Saiba como lidar com o 429 e implementar retry com backoff.

A Ticto API aplica limites de requisições por token para garantir estabilidade e desempenho para todas as integrações. Monitore os headers de rate limit em cada resposta para antecipar quando a cota está próxima de ser esgotada.

## Limites de requisições

Os limites são **por minuto** e **por token**, com cotas separadas para leitura e escrita:

| Operação | Limite |
| - | - |
| Leitura (`GET`) | 120 req/min por token |
| Escrita (`POST`) | 30 req/min por token |
| Cancelamento de assinatura (`POST /subscriptions/{id}/cancel`) | 5 req/min **e** 50 req/dia por token |
| Escopo | Por token de API |

### Por que o cancelamento tem limite próprio

Cancelar assinatura é irreversível, e o `id` da assinatura é o único parâmetro. Um limite folgado permitiria varrer `id` em busca de assinaturas de outras pessoas. Por isso a rota tem cota bem menor, com teto diário além do teto por minuto.

Além da cota, existe uma proteção extra: um token que acumula respostas `404` nessa rota (tentando `id` que não existe ou não pertence a ele) é **bloqueado temporariamente na rota**, mesmo estando dentro do limite. Uma integração normal não é afetada, porque ela cancela assinaturas que ela mesma consultou antes.

Nesse bloqueio a resposta usa o envelope padrão de erro da API:

```json Resposta 429 por varredura de id theme={null}
{
  "error": "too_many_requests",
  "message": "Too many failed lookups on this endpoint. The token is temporarily blocked.",
  "request_id": "req_xxx"
}
```

## Headers de rate limit

Toda resposta da API inclui headers informativos sobre o estado atual da cota do token utilizado:

| Header | Exemplo | Descrição |
| - | - | - |
| `X-RateLimit-Limit` | `120` | Máximo de requisições na janela de 1 minuto (120 para leitura, 30 para escrita). |
| `X-RateLimit-Remaining` | `87` | Número de requisições ainda disponíveis na janela atual. |
| `Retry-After` | `12` | Presente apenas em respostas `429`. Segundos a aguardar antes de tentar de novo. |

### Exemplo de resposta 429

Ao estourar a cota, a API retorna `429` com o corpo padrão do framework (esta resposta **não** usa o envelope `error` das demais falhas) e o header `Retry-After`:

```json Resposta 429 theme={null}
{
  "message": "Too Many Attempts."
}
```

```
Retry-After: 12
```

## Boas práticas

<Steps>
  <Step title="Verifique X-RateLimit-Remaining antes de envios em lote">
    Antes de iniciar uma operação que dispara múltiplas requisições, leia o header `X-RateLimit-Remaining` de uma chamada anterior. Se o valor estiver baixo, adicione um intervalo entre as requisições ou distribua o envio ao longo do tempo.
  </Step>

  <Step title="Implemente retry com exponential backoff ao receber 429">
    Ao receber um erro `429`, não tente novamente imediatamente. Use o valor do header `Retry-After` como base para o tempo de espera, aplicando backoff exponencial com jitter para evitar picos sincronizados em integrações paralelas.
  </Step>

  <Step title="Use Idempotency-Key para reenviar requisições POST com segurança">
    Ao reenviar uma requisição `POST` após falha de rede ou timeout, utilize o mesmo `Idempotency-Key` UUID da tentativa original. A Ticto API reconhecerá a duplicata e retornará a resposta original sem criar um segundo recurso.
  </Step>

  <Step title="Processe criações em batch com intervalos entre requests">
    Para criar múltiplos recursos em sequência (ex.: várias ofertas), adicione um intervalo de pelo menos 100–200 ms entre cada requisição. Isso evita atingir o limite em rajadas curtas e distribui a carga de forma mais previsível.
  </Step>
</Steps>

## Exemplo de retry com backoff exponencial

O exemplo abaixo implementa retry automático em JavaScript, respeitando o header `Retry-After` e aplicando backoff exponencial com jitter para tentativas subsequentes:

```javascript Retry com backoff exponencial theme={null}
async function requestWithRetry(url, options, maxRetries = 4) {
  let attempt = 0;

  while (attempt <= maxRetries) {
    const response = await fetch(url, options);

    if (response.status !== 429) {
      // Qualquer resposta que não seja 429 é retornada diretamente
      return response;
    }

    if (attempt === maxRetries) {
      // Esgotou todas as tentativas
      throw new Error(`Limite de tentativas atingido após ${maxRetries} retries.`);
    }

    // Lê o header Retry-After (em segundos) ou usa backoff exponencial como fallback
    const retryAfterHeader = response.headers.get("Retry-After");
    const retryAfterSeconds = retryAfterHeader
      ? parseInt(retryAfterHeader, 10)
      : Math.pow(2, attempt); // 1s, 2s, 4s, 8s...

    // Adiciona jitter aleatório (0–1000 ms) para evitar picos sincronizados
    const jitter = Math.random() * 1000;
    const waitMs = retryAfterSeconds * 1000 + jitter;

    console.warn(
      `Rate limit atingido. Tentativa ${attempt + 1}/${maxRetries}. ` +
      `Aguardando ${(waitMs / 1000).toFixed(1)}s...`
    );

    await new Promise((resolve) => setTimeout(resolve, waitMs));
    attempt++;
  }
}

// Exemplo de uso
const response = await requestWithRetry(
  "https://api.ticto.cloud/api/v2/products/PABC123/offers",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer {seu_token}",
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify({
      name: "Plano Mensal",
      price: 9700,
      charge_type: "one_time",
    }),
  }
);

const data = await response.json();
console.log(data);
```

<Note>
  O limite é por token de API. Você pode usar múltiplos tokens para integrar sistemas diferentes, como um token para o seu CRM e outro para o seu sistema de automação, sem que compartilhem a mesma cota de requisições.
</Note>


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