> ## 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.

# Disponibilidade e degradação

> O que acontece com o seu produto quando o nosso está num dia ruim, e as quatro linhas do seu código que decidem isso.

Estamos no caminho crítico do seu login, então a pergunta honesta não é se algum dia
vamos ficar indisponíveis. É o que o seu produto faz naquele minuto.

A resposta em torno da qual esta API foi construída, e a que você deve cobrar de nós:

<Note>
  **Nossa indisponibilidade significa "nenhuma sessão nova". Nunca significa "todo
  mundo foi desconectado".**
</Note>

São falhas separadas por uma ordem de magnitude. A primeira é um formulário de login
que diz "tente de novo em um instante". A segunda é cada um dos seus clientes jogado
fora de um produto que está funcionando perfeitamente.

## Por que existe essa diferença

Porque a verificação não chega até nós. Uma sessão de contato compra um
[JWT](/pt-br/customer-auth/session-tokens) de vida curta, e o seu backend o verifica
contra dois **documentos publicados** em vez de nos chamar:

| Documento                              | O que responde                         | Em cache por                       |
| -------------------------------------- | -------------------------------------- | ---------------------------------- |
| `GET /v1/jwks/{publishableKey}`        | quais chaves assinaram um token válido | 5 min, servível vencido por 24 h   |
| `GET /v1/revocations/{publishableKey}` | quais sessões terminaram recentemente  | 15 s, servível vencido por 15 min  |
| `GET /v1/config/{publishableKey}`      | o que uma tela de login deve desenhar  | 1 min, servível vencido por 10 min |

Os três são públicos, endereçados pelo único identificador que a sua configuração já
guarda, e cacheáveis por qualquer coisa entre você e nós. O que significa: enquanto
estamos fora, uma requisição ao seu backend com um token válido é respondida pelo seu
backend, a partir de um documento que ele já tem. Nada nessa requisição nos toca.

### Os headers, e o segundo que importa

```
Cache-Control: public, max-age=300, stale-while-revalidate=86400, stale-if-error=86400
```

`stale-while-revalidate` cobre uma nova busca **lenta**. `stale-if-error` cobre a que
volta com erro, estoura o tempo ou não pode ser feita — e é a diretiva que de fato
descreve a nossa indisponibilidade. Um cache na frente desses documentos respeita as
duas; a maioria dos clientes de JWKS também. Se você colocar os nossos documentos
atrás do seu CDN ou proxy, não remova esses headers.

<Warning>
  Todo o resto desta API responde `Cache-Control: no-store`, e isso é deliberado: essas
  respostas são a resposta à credencial de alguém, e um cache compartilhado que guarda
  uma delas entrega o dado de uma pessoa para quem chamar depois. Não configure cache
  na frente delas, e não "corrija" o header.
</Warning>

## O que para e o que continua

Leia como duas colunas, não como uma lista de falhas. A da esquerda é o que você deve
esperar que falhe; a da direita é o que precisa continuar funcionando — e sobre o que
abrir um ticket se não continuar.

| Enquanto estamos degradados                      | Para                                                                                                                     | Continua                                                                       |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
| Qualquer indisponibilidade do nosso lado         | Cadastro, login, link mágico, código por e-mail, login social, entrada na lista de espera — tudo que **cria** uma sessão | Toda sessão já criada, por todo o tempo de vida dela                           |
|                                                  | Ler o registro do próprio contato, os dispositivos dele, os times dele                                                   | O seu backend verificando tokens contra o conjunto de chaves em cache          |
|                                                  |                                                                                                                          | O seu backend recusando sessões revogadas, a partir da última lista que buscou |
| A entrega de e-mail está degradada do nosso lado | Links de verificação, links mágicos e códigos chegam atrasados ou não chegam — então esses logins não se completam       | Login por senha, login social, e toda sessão existente                         |
| Uma capacidade está indisponível no servidor     | Os endpoints que dependem dela respondem `501` e dizem qual capacidade era                                               | Tudo que não depende dela                                                      |

Duas coisas valem ser ditas porque são as que as pessoas erram:

**Um refresh de token não é uma sessão nova.** `POST /v1/contact/token` é uma leitura
do nosso lado — não cria nada. É a chamada que o seu SDK faz a cada poucos minutos
enquanto alguém estiver logado, e foi feita para continuar respondendo em condições
nas quais um login não responderia. Trate uma falha ali como transitória.

**Estourar um limite nunca bloqueia um login.** Nem o medidor de contatos ativos nem
a cota de envio são lidos por qualquer caminho de autenticação. Um limite produz um
aviso e uma fatura, nunca um `402` na frente dos seus usuários.

## As quatro linhas do seu lado

A nossa metade está acima. Esta é a sua, e é curta.

<Steps>
  <Step title="Guarde o conjunto de chaves em cache">
    Busque `GET /v1/jwks/{publishableKey}` uma vez e guarde. As bibliotecas em
    [Tokens de sessão](/pt-br/customer-auth/session-tokens#verificando) fazem isso
    por você. Um verificador que busca a cada requisição colocou o nosso uptime de
    volta na frente de toda chamada à sua API — exatamente o que o JWT existe para
    evitar.
  </Step>

  <Step title="Consulte a lista de revogação, e continue verificando quando não conseguir buscá-la">
    Uma lista que você não conseguiu atualizar degrada para "não consigo revogar mais
    rápido do que o token expira" — que é o limite que sempre existiu. Ela nunca pode
    degradar para recusar tudo. Uma lista de revogação que tranca os seus clientes
    para fora sempre que fica inalcançável é uma falha pior do que a que ela previne.
  </Step>

  <Step title="Tente o refresh de novo; nunca desconecte alguém por causa de um">
    `getToken()` falhando é um evento de rede, não um logout. Limpe a sessão quando a
    API disser que a sessão não existe mais — um `401` na superfície de contato — e
    não porque uma chamada não voltou.
  </Step>

  <Step title="Desenhe a sua tela de login a partir de um config em cache">
    `GET /v1/config/{publishableKey}` diz a uma tela o que desenhar. Guarde em cache
    (o header já pede isso) para que o formulário apareça mesmo num minuto em que não
    conseguimos responder. Uma tela que não pinta porque uma leitura de configuração
    falhou é a nossa indisponibilidade virando a sua sem motivo.
  </Step>
</Steps>

<Note>
  O `verifyContactToken` do `@userkit/nextjs` já implementa as quatro, e
  `claims.revocationCheck` diz em qual dos casos você está: `fresh`, `stale` ou
  `unavailable`. Passe `requireRevocationCheck: true` para o punhado de ações em que
  `unavailable` deve recusar — e deixe desligado em todo o resto, que é justamente o
  ponto.
</Note>

## O que não degradamos

Uma coisa corre na direção oposta, e vale saber antes de ser surpreendido: um
**captcha configurado que não pode ser verificado recusa o cadastro** com
`503 captcha_unavailable`. Ele não passa.

Isso não é um esquecimento na história de degradação, é o único ponto em que a
história se inverte. Um controle que abre sozinho quando o provedor está lento
desaparece exatamente no dia em que o tráfego que deixou o provedor lento é o motivo
de ele estar ligado. Se você prefere que uma queda do provedor deixe os cadastros
passarem, a decisão é sua e se toma desligando a exigência — não uma que nós tomamos
por você no meio de um incidente.
