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

# Rate limits

> Onde estão os limites, o que eles contam, e quais falham fechados.

Os rate limits ficam nos endpoints que um atacante alcança **sem** credencial — os
que adivinham senhas, enumeram endereços ou mandam e-mail em nome de outra pessoa.

A contagem é uma janela fixa por IP do cliente, exceto o boot, que é adicionalmente
contado por chave publicável.

## Ao ser limitado

```json 429 theme={null}
{ "error": { "code": "rate_limited", "message": "too many requests, try again later" } }
```

```
Retry-After: 3600
```

`Retry-After` carrega a janela em segundos. Espere; tentar antes só consome a
próxima janela.

## Os limites

### Autenticação de staff

| Endpoint                        | Limite     | Por que este número                                                                                                        |
| ------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------- |
| `POST /v1/auth/signup`          | 10 / hora  | Criar conta não é algo que uma pessoa faça em lote                                                                         |
| `POST /v1/auth/login`           | 20 / 5 min | Generoso para uma senha digitada errado, apertado o bastante para que credential stuffing de um endereço não seja de graça |
| `POST /v1/auth/two-factor`      | 20 / 5 min | Um código errado não consome o desafio, então é isto que limita tentativas                                                 |
| `POST /v1/auth/forgot-password` | 5 / hora   | Cada requisição envia e-mail para a caixa de outra pessoa                                                                  |
| `POST /v1/auth/reset-password`  | 10 / hora  |                                                                                                                            |

### Convites

| Endpoint                      | Limite    |
| ----------------------------- | --------- |
| `GET /v1/invitations`         | 60 / min  |
| `POST /v1/invitations/accept` | 20 / hora |

### Plano de clientes

| Endpoint                                          | Limite                                                       |
| ------------------------------------------------- | ------------------------------------------------------------ |
| `POST /v1/boot`                                   | 240 / min por IP, **e** 240 / min por chave publicável       |
| `GET /v1/jwks/{publishableKey}`                   | 120 / min — só contra abuso; um backend pode fazer polling   |
| `GET /v1/config/{publishableKey}`                 | 120 / min — cacheável; uma tela de login lê isso             |
| `POST /v1/waitlist`                               | 10 / hora — manda uma confirmação                            |
| `POST /v1/contact-auth/magic-link`                | 5 / hora                                                     |
| `POST /v1/contact-auth/magic-link/redeem`         | 20 / hora                                                    |
| `POST /v1/contact-auth/email-code`                | 5 / hora — manda e-mail para a caixa de alguém               |
| `POST /v1/contact-auth/email-code/verify`         | 20 / 5 min — e cada código carrega cinco tentativas próprias |
| `POST /v1/contact-auth/signup`                    | 10 / hora                                                    |
| `POST /v1/contact-auth/login`                     | 20 / 5 min                                                   |
| `POST /v1/contact-auth/verify-email`              | 20 / hora                                                    |
| `POST /v1/contact-auth/resend-verification`       | 5 / hora                                                     |
| `POST /v1/contact-auth/forgot-password`           | 5 / hora                                                     |
| `POST /v1/contact-auth/reset-password`            | 10 / hora                                                    |
| `POST /v1/contact-auth/two-factor`                | 20 / 5 min                                                   |
| `POST /v1/contact-auth/oauth/{provider}/start`    | 30 / hora                                                    |
| `POST /v1/contact-auth/oauth/{provider}/callback` | 30 / hora                                                    |

O limite por chave no boot existe porque a chave publicável é a fronteira de tenant
por onde uma enxurrada chega: bots e tráfego de landing page criariam linhas de
visitante para sempre.

### A superfície do próprio contato

| Endpoint                                             | Limite                    |
| ---------------------------------------------------- | ------------------------- |
| `/v1/contact/*` (tudo atrás de uma sessão `uk_ct_…`) | 600 / hora **por sessão** |

Por sessão, não por IP. Atrás do NAT de uma operadora um endereço é milhares de
pessoas, então um balde por IP numa superfície autenticada limita uma multidão
pelo que um deles fez — e a sessão é o que de fato gasta o trabalho. O
`/v1/contact/token` é a razão de o número existir: cada chamada é um decrypt de
chave e uma assinatura.

<Note>
  As demais rotas autenticadas — tudo atrás de uma sessão de staff ou de uma
  chave de API — não têm throttle. A credencial é o portão, e ela é revogável.
</Note>

## Falhar aberto, falhar fechado

Duas posturas, escolhidas por endpoint.

Os contadores vivem num store compartilhado por todas as instâncias da API.
Quando esse store não pode ser alcançado, cada instância passa a contar sozinha —
os limites continuam existindo e ficam mais frouxos, em vez de sumirem.

Isso é deliberado, e é o único lugar onde esta plataforma não degrada
graciosamente. Todo o resto que é opcional se desliga sem a sua dependência; um
cadastro público atrás de limitador nenhum é a postura de segurança inteira
desligada em silêncio, exatamente no momento em que um atacante é a explicação
mais provável.

O que você pode notar enquanto durar: um limite permitindo, por pouco tempo, um
pouco mais que o número acima, porque várias instâncias estão contando até ele
cada uma. Nada responde diferente, e não há nada para tratar.

## Ficando abaixo deles

<Steps>
  <Step title="Faça retry em 429, com backoff">
    Respeite `Retry-After` quando ele vier; use backoff exponencial quando não vier.
  </Step>

  <Step title="Não faça retry de um 4xx que não seja 429">
    Um `400` ou um `403` vai responder igual todas as vezes.
  </Step>

  <Step title="Faça debounce do boot">
    Um boot por carregamento de página, não um por componente que queira o contato.
  </Step>

  <Step title="Limite os seus próprios botões de reenvio">
    Reenvios de verificação e de magic link são 5 por hora. Um botão sem cooldown
    queima isso em segundos e o usuário só vê falha.
  </Step>
</Steps>
