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

# Quick Start: Login com a Cativa em 5 minutos

> Implemente OAuth 2.0 com PKCE e deixe usuários da Cativa entrarem no seu app.

Em 5 minutos você vai ter um botão **Entrar com Cativa** funcionando no seu app. Esse fluxo é ideal quando você quer que o usuário final autentique com a conta dele da comunidade.

<Note>
  Os endpoints SSO da Cativa seguem o padrão OIDC e são organizados por **slug do tenant** (`{customerName}`). Esse slug é o subdomínio público da comunidade — confirme com o admin do tenant qual valor usar.
</Note>

<Steps>
  <Step title="Crie um OAuth App no Console">
    Vá em [app.cativa.digital/admin/developers](https://app.cativa.digital/admin/developers), aba **OAuth Apps**, clique em **Criar app**.

    Anote o `client_id` e o `client_secret` retornados. **O secret aparece uma única vez** — guarde com cuidado.
  </Step>

  <Step title="Configure o redirect URI">
    No mesmo modal, adicione seu redirect URI (ex: `https://meuapp.com/callback` ou `http://localhost:3000/callback` para desenvolvimento).
  </Step>

  <Step title="Redirecione o usuário para o /authorize">
    No frontend, gere um `code_verifier` e `code_challenge` (PKCE) e redirecione para o endpoint `/authorize` do tenant:

    ```js theme={null}
    const verifier = generateRandomString(64);
    const challenge = await sha256(verifier);
    sessionStorage.setItem('pkce_verifier', verifier);

    const params = new URLSearchParams({
      client_id: 'CLIENT_ID_AQUI',
      redirect_uri: 'https://meuapp.com/callback',
      response_type: 'code',
      scope: 'openid profile email',
      code_challenge: challenge,
      code_challenge_method: 'S256',
      state: crypto.randomUUID()
    });

    // Substitua {customerName} pelo slug do tenant
    window.location.href = `https://apis.cativalab.digital/tenant/api/v2/sso/{customerName}/authorize?${params}`;
    ```
  </Step>

  <Step title="Troque o code por um access_token no callback">
    Depois que o usuário consente, a Cativa redireciona pra sua URL com `?code=...&state=...`. No backend, faça `POST` no endpoint `/token` do mesmo tenant com o body em `application/x-www-form-urlencoded`:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://apis.cativalab.digital/tenant/api/v2/sso/{customerName}/token \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d "grant_type=authorization_code" \
        -d "code=CODE_DO_CALLBACK" \
        -d "client_id=CLIENT_ID_AQUI" \
        -d "client_secret=SECRET_AQUI" \
        -d "redirect_uri=https://meuapp.com/callback" \
        -d "code_verifier=VERIFIER_DA_SESSION"
      ```

      ```js Node theme={null}
      const res = await fetch(`https://apis.cativalab.digital/tenant/api/v2/sso/${customerName}/token`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({
          grant_type: 'authorization_code',
          code: req.query.code,
          client_id: process.env.CATIVA_CLIENT_ID,
          client_secret: process.env.CATIVA_CLIENT_SECRET,
          redirect_uri: 'https://meuapp.com/callback',
          code_verifier: req.session.pkceVerifier
        })
      });
      const { access_token, id_token } = await res.json();
      ```

      ```python Python theme={null}
      import requests
      res = requests.post(f'https://apis.cativalab.digital/tenant/api/v2/sso/{customer_name}/token', data={
          'grant_type': 'authorization_code',
          'code': code,
          'client_id': os.environ['CATIVA_CLIENT_ID'],
          'client_secret': os.environ['CATIVA_CLIENT_SECRET'],
          'redirect_uri': 'https://meuapp.com/callback',
          'code_verifier': session['pkce_verifier']
      })
      tokens = res.json()
      ```
    </CodeGroup>

    A resposta segue o padrão OIDC e contém `access_token`, `token_type`, `expires_in` e `id_token`.
  </Step>

  <Step title="Pegue informações do usuário">
    Use o `access_token` no endpoint userinfo:

    ```bash theme={null}
    curl https://apis.cativalab.digital/tenant/api/v2/sso/{customerName}/userinfo \
      -H "Authorization: Bearer ACCESS_TOKEN"
    ```

    Resposta:

    ```json theme={null}
    {
      "sub": "01HQ7Z3X4Y5Z6A7B8C9D0E1F2G",
      "name": "Maria Silva",
      "email": "maria@exemplo.com",
      "picture": "https://cdn.cativa.digital/avatars/..."
    }
    ```
  </Step>
</Steps>

<Note>
  O documento de descoberta OIDC do tenant fica em `https://apis.cativalab.digital/tenant/api/v2/sso/{customerName}/.well-known/openid-configuration` e lista todos os endpoints (`authorize`, `token`, `userinfo`, `jwks`) e algoritmos suportados (`S256` para PKCE, `ES256` para assinatura do `id_token`). O JWKS público fica em `https://apis.cativalab.digital/tenant/api/v2/sso/{customerName}/jwks`. Bibliotecas como [jose](https://www.npmjs.com/package/jose) (Node) ou [PyJWT](https://pyjwt.readthedocs.io/) (Python) leem o discovery e validam o `id_token` automaticamente.
</Note>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Tenants e Customers" icon="building" href="/pt-BR/concepts/tenants-and-customers">
    Entenda o conceito de `customerName` no fluxo OIDC e quando o tenant aparece nas integrações.
  </Card>

  <Card title="Primeira chamada de API" icon="terminal" href="/pt-BR/get-started/quickstart-api-key">
    Para integrações server-to-server, use API Key direto em vez de OAuth.
  </Card>
</CardGroup>
