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

# Microsoft 365 (SharePoint)

> Lê arquivos de bibliotecas de documentos do SharePoint com uma App Registration do Microsoft Entra, extrai o texto e envia os documentos para o Knowledge com a permissão de cada arquivo.

O conector Microsoft 365 lê os arquivos das bibliotecas de documentos dos sites do SharePoint que você seleciona, extrai o texto de cada um e envia os documentos para o Knowledge. Cada documento carrega a lista de pessoas e grupos que podem abri-lo no SharePoint.

| | |
| - | - |
| **Status** | Beta |
| **Conteúdo** | Documentos |
| **Autenticação** | App Registration do Microsoft Entra (client credentials) |
| **Permissões** | Por item |
| **Sincronização** | Incremental |
| **Última revisão** | 21/10/2026 |

## Capacidades

* **Knowledge.** O texto de arquivos PDF, Word (`.docx`), CSV e Markdown é enviado como documento, com nome, caminho (site, biblioteca e pastas) e link para abrir o arquivo no SharePoint.
* **Permissão da fonte.** A permissão de cada arquivo é lida no SharePoint e guardada junto com o documento. No modo "Espelhar a fonte", cada pessoa encontra nas buscas só os arquivos que ela pode abrir.
* **Todas as bibliotecas do site.** De cada site selecionado, o conector lê todas as bibliotecas de documentos, não só a padrão.

O conector não alimenta o Data Catalog nem o Memory: os arquivos vão só para o Knowledge.

## Recursos disponíveis

| Recurso | O que contém | Carga | Cursor | Destino | Permissão por item |
| - | - | - | - | - | - |
| `documents` | Um registro por arquivo das bibliotecas selecionadas e das subpastas: nome, tipo, caminho, site, datas de criação e modificação e link. O texto extraído segue para o Knowledge | Incremental | `modified_at` | Knowledge | Sim |

Cada biblioteca tem o próprio cursor. Uma biblioteca nova é lida inteira.

## Permissões (ACL)

O conector lê a permissão de cada item na fonte e a guarda junto com o dado. Em **Comportamento dos dados**, você escolhe entre dois modos:

| Modo | Quem vê |
| - | - |
| Aberto | Quem puder usar este conector vê todos os registros. As permissões da fonte são ignoradas. |
| Espelhar a fonte | Cada pessoa vê apenas os registros que a própria fonte libera para ela. |

No modo "Espelhar a fonte", marque **Exigir login na fonte como prova de identidade**. O Microsoft 365 identifica cada pessoa por um id próprio, não pelo e-mail, então a Strattum só reconhece quem se autenticou no Microsoft 365.

### Como a fonte define acesso

No SharePoint, cada arquivo tem a própria lista de acesso. Ela reúne o que foi concedido direto no arquivo e o que ele herda da pasta, da biblioteca e do site. Uma concessão pode ser a uma pessoa, a um grupo do Microsoft Entra, a um grupo do SharePoint do site ou a um link de compartilhamento.

### Como a Strattum traduz o acesso

Para cada arquivo, o conector lê a lista de acesso no Microsoft Graph e grava os leitores assim:

| Concessão no SharePoint | O que a Strattum grava |
| - | - |
| Uma pessoa | a pessoa, pelo ID de objeto dela no Microsoft Entra |
| Um grupo do Microsoft Entra | o grupo, pelo ID de objeto dele |
| Um grupo do SharePoint do site | o arquivo inteiro fica sem leitor |
| Um link de compartilhamento, de qualquer escopo | o arquivo inteiro fica sem leitor |
| Qualquer outra identidade, como um aplicativo | o arquivo inteiro fica sem leitor |

A regra é tudo ou nada por arquivo. Se uma única concessão não pode ser traduzida, a lista inteira é descartada. Por exemplo: um relatório compartilhado com três pessoas e também com um link de compartilhamento fica sem leitor.

> [!WARNING]
>
> No modo "Espelhar a fonte", um arquivo sem leitor não é indexado. Isso vale para qualquer arquivo com concessão a um grupo do SharePoint do site ou a um link de compartilhamento. Para indexá-lo agora, use "Aberto" e limite o acesso em **Quem pode usar este conector**.

Os membros de cada grupo do Entra são lidos à parte, no Microsoft Graph, com a mesma App Registration. Grupos dentro de grupos entram na lista. Assim, quem está num grupo com acesso ao arquivo encontra o arquivo, desde que tenha vinculado a conta.

No vínculo de conta, o login acontece no endereço do tenant da conexão. A conta precisa existir no diretório desse tenant, convidados incluídos.

### Quando a identidade não é encontrada

No modo "Espelhar a fonte", quem não casa com nenhum leitor do arquivo não o encontra nas buscas. Isso acontece quando a pessoa não vinculou a conta Microsoft. Também acontece quando o acesso dela vem de um grupo cujos membros não puderam ser lidos. Um único grupo que falha na leitura, por exemplo porque falta a permissão `GroupMember.ReadBasic.All`, faz a Strattum manter a lista de membros anterior de todos os grupos da conexão naquela rodada.

Um arquivo sem nenhum leitor não é indexado no modo "Espelhar a fonte". Ele aparece como não indexado, com o motivo "Permissões não puderam ser resolvidas com segurança". No modo "Aberto", o arquivo é indexado mesmo sem leitores.

### Quando a permissão é atualizada

A lista de acesso é lida no mesmo sync em que o arquivo é lido, com uma chamada ao Graph por arquivo. Numa sincronização incremental, o conector só relê arquivos cuja data de modificação (`lastModifiedDateTime`) mudou desde a última execução. Se o compartilhamento muda e a data de modificação não, o documento mantém a permissão antiga até o arquivo ser editado ou até a próxima verificação completa.

Se a leitura da permissão de um arquivo falha no modo "Espelhar a fonte", a biblioteca não avança a data de corte e o arquivo é tentado de novo na execução seguinte.

Os membros dos grupos são relidos por uma rotina própria, a cada 10 minutos por padrão.

## Pré-requisitos

* Um tenant Microsoft 365 com sites do SharePoint.
* Uma App Registration no Microsoft Entra (antigo Azure AD) com as permissões de aplicação `Sites.Read.All` e `Files.Read.All` do Microsoft Graph, com consentimento de administrador.
* O **Tenant ID**, o **Client ID** e um **Client Secret** dessa App Registration.
* Para o modo "Espelhar a fonte" com grupos: a permissão de aplicação `GroupMember.ReadBasic.All`, ou uma superior, na mesma App Registration.
* Para exigir login na fonte: um aplicativo do Entra ID com a permissão delegada `User.Read`, de onde saem o **Client ID** e o **Client Secret** do login. Eles são informados à parte da credencial da conexão.
* No Console, permissão para editar conectores e, para definir o acesso, permissão em configurações de ACL.

## Autenticação e escopos

O conector age como a própria aplicação, sem um usuário. Ele pede um token ao Microsoft Entra pelo fluxo client credentials, com o escopo `https://graph.microsoft.com/.default`, então vale o que o administrador consentiu na App Registration. Permissões delegadas não servem para a conexão.

| Escopo ou permissão | Para quê |
| - | - |
| `Sites.Read.All` (Graph, aplicação) | Listar os sites do tenant e as bibliotecas de cada site |
| `Files.Read.All` (Graph, aplicação) | Percorrer as pastas, baixar o conteúdo dos arquivos e ler a permissão de cada arquivo |
| `GroupMember.ReadBasic.All` (Graph, aplicação) | Opcional. Ler os membros dos grupos do Entra que têm acesso a arquivos, no modo "Espelhar a fonte". Uma permissão superior também serve |
| `User.Read` (Graph, delegada) | Vínculo de conta: identificar a pessoa que entra. Vale para o aplicativo de login, não para a conexão |

> [!WARNING]
>
> Com `Sites.Read.All` e `Files.Read.All`, o aplicativo pode ler todos os sites e arquivos do tenant, e não só os que você seleciona no Data Catalog. O conector lê apenas a seleção, mas a credencial alcança tudo. Conceda o consentimento com esse alcance em mente.

**1. Registre o aplicativo**

No Microsoft Entra admin center, acesse **Entra ID** > **App registrations** e clique em **New registration**. Dê um nome e, em **Supported account types**, a Microsoft recomenda **Single tenant only**. Clique em **Register** e copie o **Application (client) ID** da tela **Overview**. O **Tenant ID** é o GUID do diretório ou o domínio dele, como `contoso.onmicrosoft.com`.

**2. Conceda as permissões**

Na App Registration, acesse **API permissions** > **Add a permission** > **Microsoft Graph** > **Application permissions**. Marque `Sites.Read.All` e `Files.Read.All`, e também `GroupMember.ReadBasic.All` se for usar o modo "Espelhar a fonte". Clique em **Add permissions**. Depois clique em **Grant admin consent** (o botão traz o nome do seu tenant) e confirme.

**3. Gere o client secret**

Acesse **Certificates & secrets** > **Client secrets** > **New client secret**. Informe uma descrição e uma validade, e clique em **Add**. Copie o **Value** na hora: ele não é mostrado de novo. A Microsoft limita a validade a 24 meses e recomenda menos de 12.

## Configuração no Console

**1. Preencha a conexão**

**Nome do Conector** (Opcional): um nome para identificar esta instância. O padrão é `Microsoft 365`.

**Tenant ID** (Obrigatório): o GUID ou o domínio do tenant. O vínculo de conta recusa `common`, `organizations` e `consumers`.

**Client ID** (Obrigatório): o Application (client) ID da App Registration.

**Client Secret** (Obrigatório): o Value do segredo.

Clique em **Conectar e listar sites**. O Console autentica no Microsoft Graph, mostra quantos sites encontrou e só avança depois desse teste bem-sucedido. A lista serve para conferir as credenciais. Quais sites o conector lê é escolhido depois, no Data Catalog.

**2. Defina a frequência**

**Frequência de Sincronização** (Obrigatório): o recomendado é **A cada 6h (recomendado)**. Também há opções prontas, de 10 minutos a semanal, e **Personalizado**, para informar uma **Expressão Cron**. Os horários são em UTC. Veja [Frequência de sync](https://docs.strattum.ai/data-pipelines/sync-frequency.md).

**3. Configure o permissionamento**

**Quem pode usar este conector** (Obrigatório): "Todos os usuários" ou "Apenas times específicos". Na segunda opção, selecione os **Times com acesso**.

**Comportamento dos dados** (Obrigatório): "Aberto" ou "Espelhar a fonte".

**Exigir login na fonte como prova de identidade** (Quando selecionado "Espelhar a fonte"): marque para que cada usuário vincule a conta Microsoft.

**URL de autenticação**, **Client ID** e **Client Secret** (Quando selecionado o login na fonte, obrigatórios): os dados do aplicativo de login do Entra ID. A URL tem o formato `https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize`, com o seu Tenant ID no lugar de `TENANT_ID`.

**Escopos** (Opcional): o login pede `openid profile User.Read` quando o campo fica vazio.

**4. Revise e salve**

Confira os campos e salve. O Console aceita salvar sem escolher sites, mas a sincronização fica aguardando configuração até existir pelo menos um site ou uma biblioteca.

**5. Escolha os sites no Data Catalog**

Abra o conector no Data Catalog, na seção **Documentos no catálogo**. Marque os sites que o conector deve ler e clique em **Salvar seleção**. Se o Console não conseguir listar os sites, o campo vira **IDs de sites**, com um ID por linha. Depois de salvar, o Console diz se a carga completa já foi agendada. Se não foi, execute a carga para atualizar os documentos.

**IDs de bibliotecas** (Opcional): um ID de biblioteca ou de unidade (drive) do Microsoft Graph por linha, para ler uma unidade específica sem selecionar o site inteiro. A lista de sites do Console não inclui os sites pessoais do OneDrive, então um OneDrive só entra por este campo.

## Como a sincronização funciona

O agendamento recomendado roda a cada 6 horas. A cada execução, o conector abre cada site selecionado, lista as bibliotecas dele e percorre as pastas, 200 itens por página, até o 10º nível de subpastas. Uma execução tem o limite de 2 horas.

**Leitura.** A primeira execução lê todas as bibliotecas dos sites selecionados. As seguintes leem só os arquivos com data de modificação no SharePoint (`lastModifiedDateTime`) posterior à última execução de cada biblioteca. As pastas são sempre percorridas, porque a data de uma pasta não muda quando um arquivo dentro dela muda. Só a versão atual de cada arquivo é lida.

**Cada arquivo.** O documento é identificado pelo ID da biblioteca e do arquivo no SharePoint, e não pelo nome. Um arquivo editado e salvo mantém o ID, e o Knowledge troca o conteúdo antigo pelo novo, sem duplicar. Um arquivo apagado e enviado de novo, mesmo com o mesmo nome, ganha outro ID e entra como documento novo. Um arquivo fica fora do Knowledge quando:

* o formato não é suportado;
* tem mais de 50 MB;
* é um arquivo vazio, ou não tem texto, como um PDF escaneado;
* o download ou a leitura do texto falhou, como num PDF protegido por senha;
* no modo "Espelhar a fonte", a permissão não pôde ser traduzida (veja "Permissões").

A data de corte de uma biblioteca só avança quando a execução leu a biblioteca inteira, sem erro de pasta, de download, de leitura ou de permissão. Com erro, a execução seguinte lê a mesma janela de novo. Um arquivo grande demais não segura a data de corte, porque ele continuaria grande na próxima vez.

**Arquivos removidos.** A sincronização incremental não remove documentos. Uma vez por dia, na **Janela de manutenção** (padrão 03:00 no fuso configurado no servidor, ou UTC), o conector faz uma verificação completa: lê todos os sites selecionados e remove do Knowledge os arquivos que não existem mais no SharePoint. O mesmo vale para os arquivos de um site que você tira da seleção. Se algum site ou biblioteca falha nessa leitura, ou se há pastas além do 10º nível, nada é removido naquele dia. O horário é ajustado em **Editar** > **Sincronização** > **Janela de manutenção**.

Casos e prazos de cada mudança estão em [Atualização e remoção de documentos](https://docs.strattum.ai/data-pipelines/document-updates.md).

## API da fonte

O conector usa o Microsoft Graph v1.0. A autenticação passa pelo Microsoft Entra, com a biblioteca MSAL.

| Método e caminho | Usado para | Recurso |
| - | - | - |
| `GET /sites/{site}` | Resolver cada site selecionado e testar a conexão | `documents` |
| `GET /sites/getAllSites` | Listar os sites do tenant no Console, sem os sites pessoais, e testar a conexão quando só há bibliotecas selecionadas por ID | Nenhum |
| `GET /sites/{site}/drives` | Listar as bibliotecas de cada site | `documents` |
| `GET /drives/{drive}/root/children` e `GET /drives/{drive}/items/{item}/children` | Percorrer as pastas e listar os arquivos | `documents` |
| `GET /drives/{drive}/items/{item}/content` | Baixar o conteúdo de cada arquivo | `documents` |
| `GET /drives/{drive}/items/{item}/permissions` | Ler a permissão de cada arquivo | Permissões |
| `GET /groups/{id}/transitiveMembers/microsoft.graph.user` | Ler os membros de cada grupo do Entra com acesso a arquivos | Permissões |
| `GET /me` | Vínculo de conta: ler o ID e o e-mail de quem entra, com o token da própria pessoa | Permissões |

**Rate limits.** Limite da API: o SharePoint e o OneDrive medem o uso do Graph em unidades de recurso, por aplicativo e por tenant. Baixar um arquivo custa 1 unidade, listar uma pasta custa 2 e toda chamada de permissões custa 5. Por arquivo, o conector faz um download e uma leitura de permissões. Estourar o limite devolve `429` ou `503` com o cabeçalho `Retry-After`. Os valores padrão dependem do número de licenças do tenant e a Microsoft pode mudá-los ([documentação](https://learn.microsoft.com/en-us/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online)):

| Licenças do tenant | Por minuto, por aplicativo | Por 24 horas, por aplicativo | Em 5 minutos, todos os aplicativos do tenant |
| - | - | - | - |
| Até 1.000 | 1.250 | 1.200.000 | 18.750 |
| De 1.001 a 5.000 | 2.500 | 2.400.000 | 37.500 |
| De 5.001 a 15.000 | 3.750 | 3.600.000 | 56.250 |
| De 15.001 a 50.000 | 5.000 | 4.800.000 | 75.000 |
| Mais de 50.000 | 6.250 | 6.000.000 | 93.750 |

Comportamento do conector: as chamadas são feitas uma de cada vez. Ao receber `429` ou `503`, o conector espera o tempo do cabeçalho `Retry-After`, até 60 segundos. Sem o cabeçalho, espera 2 segundos e dobra a cada tentativa, também até 60. Depois de 5 repetições, a falha segue para o item: uma pasta que não lista é pulada, um arquivo que não baixa fica de fora e uma permissão que não lê deixa o arquivo sem leitor. Nos três casos, a biblioteca não avança a data de corte (no modo "Aberto", a permissão não lida não a segura). Outros erros HTTP, como `401` e `403`, não são repetidos. Se a extração falha por inteiro, a plataforma a refaz até 3 vezes, depois de 1, 2 e 4 minutos.

Referência oficial: [https://learn.microsoft.com/en-us/graph/api/resources/driveitem](https://learn.microsoft.com/en-us/graph/api/resources/driveitem)

## Limitações conhecidas

* Só entram arquivos PDF, Word (`.docx`), CSV e Markdown. Excel, PowerPoint, o formato Word antigo (`.doc`), imagens e outros tipos são ignorados, sem aviso e sem aparecer na lista de documentos ignorados.
* Arquivos com mais de 50 MB não são lidos.
* PDF escaneado (só imagem) não tem texto extraído, porque não há OCR. PDF protegido por senha ou corrompido não é lido.
* Em arquivos Word, cabeçalhos e rodapés não são extraídos.
* Arquivo vazio (0 bytes) é ignorado.
* O histórico de versões do SharePoint não é indexado. Só a versão atual de cada arquivo entra no Knowledge.
* Arquivo apagado no SharePoint continua no Knowledge até a próxima verificação completa da Janela de manutenção.
* Uma mudança de permissão que não altera a data de modificação do arquivo só chega ao Knowledge na próxima verificação completa.
* No modo "Espelhar a fonte", um arquivo com concessão a um grupo do SharePoint do site, a um link de compartilhamento ou a um aplicativo não é indexado. No modo "Aberto", ele é indexado.
* No modo "Espelhar a fonte", quem não vinculou a conta Microsoft não encontra nenhum arquivo. A Strattum não deduz a pessoa pelo e-mail.
* Se a leitura dos membros de um único grupo do Entra falha, nenhuma lista de membros é atualizada naquela rodada.
* Os campos de filtro de pastas e de profundidade não existem no Console. Subpastas além do 10º nível não são lidas.
* Uma biblioteca informada por ID aparece com o caminho começando em `OneDrive`, sem o nome do site.
* A lista de sites do Console não inclui os sites pessoais do OneDrive. Um OneDrive só entra pelo campo **IDs de bibliotecas**.
* A conexão usa permissões de aplicação. Permissões delegadas, por usuário, não são o fluxo suportado.
* O client secret expira. Quando isso acontece, a sincronização falha até você gerar outro segredo e informá-lo em **Editar** > **Conexão**, junto com o Tenant ID e o Client ID.

## Troubleshooting

| Mensagem ou sintoma | Causa | O que fazer |
| - | - | - |
| "Falha ao obter token do Microsoft 365: ..." | O Microsoft Entra recusou o Tenant ID, o Client ID ou o Client Secret, ou o segredo expirou | Confira os três valores na App Registration e gere outro segredo se o atual expirou. O fim da mensagem traz o código de erro do Entra |
| "Erro ao listar sites do SharePoint: ..." | O token foi emitido, mas o Graph recusou a listagem | Confirme que `Sites.Read.All` e `Files.Read.All` são permissões de aplicação e que o consentimento de administrador foi concedido |
| "O conector Microsoft 365 está com credenciais incompletas." | O conector salvo não tem Tenant ID, Client ID ou Client Secret | Em **Editar** > **Conexão**, preencha os três campos de novo |
| "Nenhum site encontrado" | A App Registration autenticou, mas o Graph não devolveu sites, ou o tenant só tem sites pessoais | Verifique as permissões de aplicação e se há sites do SharePoint no tenant |
| A sincronização não começa e o log diz `Microsoft 365 has no SharePoint site selected` | Nenhum site nem biblioteca foi selecionado | Em **Documentos no catálogo**, no Data Catalog, marque ao menos um site e clique em **Salvar seleção** |
| A sincronização falha com `Microsoft 365 connection test failed` | O teste de conexão da execução falhou: credenciais, segredo expirado ou site sem acesso | Confira as credenciais e o log da execução |
| Arquivo não aparece no Knowledge, com o motivo "Permissões não puderam ser resolvidas com segurança" | O arquivo tem concessão a um grupo do SharePoint do site, a um link de compartilhamento ou a um aplicativo, ou não tem nenhum leitor | Use o modo "Aberto", ou troque a concessão por pessoas e grupos do Entra |
| Arquivo não aparece, com o motivo "Falha ao baixar o arquivo do conector" | O download falhou depois das repetições, por limite do Graph ou falta de acesso | Veja o log. A biblioteca é lida de novo na próxima execução |
| Arquivo não aparece, com o motivo "Falha ao ler o conteúdo do arquivo" | O PDF é protegido por senha ou corrompido, ou o Word está malformado | Reenvie o arquivo sem senha e sem corrupção |
| Arquivo não aparece, com o motivo "Sem conteúdo indexável após leitura/OCR" | O arquivo é vazio, ou o PDF é escaneado e não tem texto | Envie uma versão com texto selecionável |
| Arquivo Excel ou PowerPoint não aparece | O conector ignora esses formatos | Salve uma cópia em PDF ou Word na mesma biblioteca |
| Um usuário não vê nada no modo "Espelhar a fonte" | Ele não vinculou a conta Microsoft, ou o acesso dele vem de um grupo cujos membros não puderam ser lidos | Peça ao usuário para vincular a conta e confira a permissão `GroupMember.ReadBasic.All` e o consentimento dela |
| O vínculo da conta Microsoft falha | A conta não existe no diretório do tenant da conexão, ou o `User.Read` não tem consentimento no aplicativo de login | Use uma conta desse diretório e confira se o `User.Read` está consentido no aplicativo de login |

## Próximos passos

> **[Knowledge](https://docs.strattum.ai/knowledge/overview.md)**
>
> Veja como buscar nos documentos que o conector envia.

> **[Data Catalog](https://docs.strattum.ai/data-catalog/overview.md)**
>
> Conheça o catálogo, onde você escolhe os sites que o conector lê.

> **[Atualização e remoção de documentos](https://docs.strattum.ai/data-pipelines/document-updates.md)**
>
> O que acontece no Knowledge quando um arquivo é editado, substituído ou apagado.

> **Desenvolvimento local**
>
> No ambiente local, as credenciais do conector são cadastradas pelo Console (veja [Desenvolvimento local](https://docs.strattum.ai/data-pipelines/local-development.md)). O segredo fica no cofre de credenciais da instância, e não no `.env`.
>
> A sincronização lê estas chaves de credencial do conector:
>
> | Chave | Descrição | Exemplo |
> | - | - | - |
> | `M365_TENANT_ID` | GUID ou domínio do tenant | `contoso.onmicrosoft.com` |
> | `M365_CLIENT_ID` | Application (client) ID da App Registration | `00000000-0000-0000-0000-000000000000` |
> | `M365_CLIENT_SECRET` | Value do client secret | |
> | `M365_SELECTED_SITES` | IDs ou hostnames dos sites, em lista JSON ou separados por vírgula | `["contoso.sharepoint.com:/sites/intranet"]` |
> | `M365_SELECTED_DRIVES` | IDs de bibliotecas ou unidades | `["b!abc..."]` |
> | `M365_INCLUDE_FOLDERS` | Prefixos de pasta a incluir, no formato `Site/Biblioteca/pasta`. Vazio inclui tudo | `["Intranet/Documents/contratos"]` |
> | `M365_EXCLUDE_FOLDERS` | Prefixos de pasta a excluir, no mesmo formato. Vazio não exclui nada | `["Intranet/Documents/arquivo-morto"]` |
> | `M365_MAX_DEPTH` | Níveis máximos de subpastas. O padrão é 10 | `10` |
>
> O Console não preenche `M365_INCLUDE_FOLDERS`, `M365_EXCLUDE_FOLDERS` nem `M365_MAX_DEPTH`. Quem executa a classe do conector direto, fora do Console, pode passá-los a `authenticate()` como `include_folders`, `exclude_folders` e `max_depth`.


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