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

# Login único (SAML)

> Troque a API key da sua instituição mais uma asserção SAML por uma sessão de médico

Com o login único SAML a sua instituição tem **uma** API key em vez de uma key por médico. Seu provedor de identidade (Okta, Azure AD, ADFS…) autentica o médico, e seu backend troca a key da instituição mais uma asserção SAML assinada por um **token de sessão do médico**. Todos os endpoints de negócio continuam iguais — só muda o valor de `Authorization`.

## Como funciona

1. Seu IdP autentica o médico e assina uma asserção SAML.
2. Seu backend chama `POST /v1/sso/exchange` com a secret key da sua instituição e a asserção.
3. A Telepatia verifica a assinatura, o emissor, a audiência e a validade contra a configuração SAML da sua instituição, e devolve um access token do médico mais um refresh token.
4. Seu backend chama a API com o token do médico e o renova com `POST /v1/sso/refresh` — sem nova ida ao IdP até a cadeia de refresh terminar.

## Pré-requisitos

* Uma **secret key** de instituição (`sk_…`) criada com a permissão **SAML SSO exchange** (a caixa `saml:exchange` na página de API Keys da plataforma).
* A configuração SAML salva na aba **Developers → SSO** da plataforma: o entity ID (emissor) do seu IdP e o certificado de assinatura dele.
* O médico já precisa existir na sua instituição. O SSO autentica médicos; não os cria.

## Dados do Service Provider

Registre estes valores fixos da Telepatia no seu provedor de identidade. São os mesmos para todas as instituições.

| Valor                         | URL                                               |
| ----------------------------- | ------------------------------------------------- |
| SP entity ID (audiência)      | `https://scribe-api.telepatia.ai/saml`            |
| ACS URL (destino da asserção) | `https://scribe-api.telepatia.ai/v1/sso/exchange` |
| URL de metadata do SP         | `https://scribe-api.telepatia.ai/v1/sso/metadata` |

## Trocar uma asserção

Envie a resposta SAML codificada em base64 com a key da sua instituição:

```bash theme={null}
curl -X POST https://scribe-api.telepatia.ai/v1/sso/exchange \
  -H "Authorization: Bearer YOUR_INSTITUTION_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "samlResponse": "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46..."
  }'
```

Resposta `200`:

```json theme={null}
{
  "documentId": "acc_1234567890",
  "token": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "expiresIn": 3600,
    "refreshToken": "4167f20c-d620-40c4-b0f3-8f2a1c9e7d55"
  }
}
```

Guarde a sessão e reutilize até expirar. Cada asserção é de **uso único** — uma segunda troca com a mesma asserção devolve `403`.

## Requisitos da asserção

* A **asserção é assinada** (RSA-SHA256, assinatura envelopada) com o certificado configurado para a sua instituição.
* O `Issuer` é igual ao entity ID do IdP configurado para a sua instituição.
* O `Audience` é igual ao SP entity ID acima.
* O `Destination` é igual à ACS URL acima.
* A janela de validade (`NotBefore` / `NotOnOrAfter`) cobre o momento da troca.
* A asserção inclui um **`AttributeStatement`** — IdPs padrão sempre incluem.
* O e-mail do médico chega como `NameID` do sujeito (formato `emailAddress`), ou no atributo indicado pelo ajuste opcional **email attribute**.

## Renovar a sessão

O refresh token é a credencial — sem key de instituição e sem asserção:

```bash theme={null}
curl -X POST https://scribe-api.telepatia.ai/v1/sso/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "4167f20c-d620-40c4-b0f3-8f2a1c9e7d55"
  }'
```

A resposta traz a mesma forma de sessão da troca. Refresh tokens **rotacionam**: o anterior é revogado quando o par novo é emitido, e reutilizá-lo devolve `401`.

## Chamar a API como o médico

Use o access token exatamente onde iria a API key:

```bash theme={null}
curl https://scribe-api.telepatia.ai/v1/scribe-session-configurations \
  -H "Authorization: Bearer DOCTOR_ACCESS_TOKEN"
```

## Respostas de erro

| Código | Significado                                                                                                          |
| ------ | -------------------------------------------------------------------------------------------------------------------- |
| `401`  | Key de instituição inválida ou expirada, ou um refresh token já rotacionado                                          |
| `403`  | SSO desabilitado, key sem a permissão `saml:exchange`, asserção reutilizada, ou médico não vinculado à instituição   |
| `422`  | A asserção falhou na verificação: assinatura, emissor, audiência, destino, validade, ou falta o `AttributeStatement` |

### Exemplo: asserção reutilizada

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "permission_denied",
    "message": "SAML assertion could not be exchanged for a session."
  }
}
```

### Exemplo: asserção inválida

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "SAML assertion could not be exchanged for a session."
  }
}
```
