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

# API

> Liga o acesso de programas ao servidor, e cria as chaves que autorizam cada um. É por aqui que um sistema de fora cria cliente, domínio, conta de e-mail ou banco de dados sem…

**Caminho no painel:** menu da esquerda > Configuração > cartão **Painel de
Controle** > **API**

![Tela da API: a versão, a chave Ativado, o botão Opções e a lista de chaves com prefixo, IPs e último acesso](https://mintcdn.com/san-internet/dZE3NBY61yDby7Jw/keyhelp-admin/imagens/controle-api.png?fit=max\&auto=format\&n=dZE3NBY61yDby7Jw\&q=85\&s=dde5b527a61fc189b9c09ba10222ba17)

Nesta instalação a tela mostra **Versão da API: 2.15**, e o painel é o 26.1.1.

## Ligar e desligar

Em **Acesso da API**, o botão alterna entre ligado e desligado, e o painel
responde que as configurações foram atualizadas.

> [!WARNING]
>
> **Desligada, a API responde em HTML, e não no formato que o programa espera**
>
> Medido: com o acesso desligado, uma chamada volta com o código **403** e o
> corpo `API is disabled.` em `text/html`. Todo o resto da API responde em JSON.
> Um programa que leia a resposta como JSON quebra na hora de interpretar, em vez
> de mostrar o motivo real. Vale prever esse caso no lado de quem consome.

## Como um programa se autentica

| Item | Valor |
| - | - |
| Endereço base | `https://<seu-servidor>/api/v2/` |
| Cabeçalho de autenticação | `X-API-Key: <chave>` |
| Formato de envio | `application/json` |
| Formatos de resposta | `application/json` (padrão), `application/xml`, `text/yaml`, escolhidos no cabeçalho `Accept` |

**Conferido:** os três formatos de resposta funcionam. A mesma consulta devolveu
JSON, XML e YAML conforme o `Accept` enviado.

**A sessão do painel não serve para a API.** Medido: uma chamada feita do próprio
navegador com o administrador logado, e sem a chave, foi recusada do mesmo jeito.
O cookie de sessão não vale como autorização, e isso é o comportamento correto.

### A documentação vem do próprio servidor

A tela traz três links: a referência em um site do fabricante, e a especificação
OpenAPI nos formatos **JSON** e **YAML**, servida pelo próprio painel em
`/api/openapi.json` e `/api/openapi.yml`.

**Esses dois arquivos respondem sem chave nenhuma.** É documentação, não dado do
servidor, e ter a especificação da versão exata instalada vale mais que a
referência genérica do site.

## Criar uma chave

1. Clique em **Adicionar chave API**.
2. Em **Nome**, escreva algo que identifique quem vai usar a chave.
3. Em **IPs**, escreva os endereços ou faixas que podem usá-la.
4. Clique em **Salvar**.

![Formulário de criação: o campo Nome, o campo IPs e os avisos sobre a chave não ficar guardada em texto claro](https://mintcdn.com/san-internet/dZE3NBY61yDby7Jw/keyhelp-admin/imagens/controle-api-adicionar.png?fit=max\&auto=format\&n=dZE3NBY61yDby7Jw\&q=85\&s=640ea909cd749ab200f3c63e710bfb30)

A chave aparece **uma única vez**, logo depois de salvar, e não há como recuperá-la
depois.

![Aviso verde dizendo que a chave foi criada, com o valor dela abaixo](https://mintcdn.com/san-internet/dZE3NBY61yDby7Jw/keyhelp-admin/imagens/controle-api-chave-criada.png?fit=max\&auto=format\&n=dZE3NBY61yDby7Jw\&q=85\&s=21c2e80e3e5c0ced17ed0c9e9d8ded5d)

**Conferido no servidor:** a chave tem **129 caracteres**, no formato
`prefixo.segredo`, com 8 caracteres de prefixo e 120 de segredo. Na tabela do
painel fica guardado o prefixo em texto claro e um **resumo criptográfico de 69
caracteres** no lugar do segredo. O que a tela promete se confirma no banco: o
segredo não está lá.

O prefixo é o que aparece na coluna **PREFIXO DA CHAVE API** da lista, e serve
para você saber de qual chave se trata sem ter o valor dela.

> [!WARNING]
>
> **Chave sem lista de IPs fica sem a barreira de endereço**
>
> O campo **IPs** não é obrigatório. A própria tela recomenda restringir cada
> chave a um ou mais endereços, e a lista é a única barreira de endereço que a
> chave tem. Como a chave vale para o servidor inteiro, e a opção
> padrão ignora os limites das contas, uma chave solta é o acesso mais amplo que
> existe neste painel.

### A recusa por IP é indistinguível de chave errada

**Medido**, com duas chaves criadas para o teste:

| Situação | Resposta |
| - | - |
| Chave certa, IP autorizado | **200**, com o conteúdo pedido |
| Chave certa, **IP fora da lista** | **401**, `API key is invalid / You are not allowed to access the API due to IP restrictions.` |
| Chave inexistente | **401**, **a mesma mensagem** |
| Nenhuma chave enviada | **401**, `API key is missing.` |

A mensagem não separa "a chave está errada" de "a chave está certa e o IP não
pode". Quem estiver depurando uma integração que parou de funcionar precisa
conferir os dois lados, e a lista de IPs costuma ser o culpado quando o servidor
que consome muda de endereço.

## As Opções, que o botão esconde

O botão **Opções** abre três ajustes que valem para a API inteira.

![Modal Opções, com as três chaves: ignorar limites, aplicar política de senha e usar hashes de senha](https://mintcdn.com/san-internet/dZE3NBY61yDby7Jw/keyhelp-admin/imagens/controle-api-opcoes.png?fit=max\&auto=format\&n=dZE3NBY61yDby7Jw\&q=85\&s=539f6f6d10aaea1275e6fe4214df0705)

| Opção | Vem com | O que faz |
| - | - | - |
| **Ignorar limites de recursos de contas de usuário** | **ligada** | deixa a API criar recurso além do limite do plano do cliente |
| **Aplique a política de senha ao usar a API** | desligada | com ela ligada, a API recusa senha que não atenda à política do painel |
| **Usar hashes de senha** | desligada | liga o campo `password_hash`, que lê e grava o resumo da senha em vez da senha |

> [!WARNING]
>
> **O padrão deixa a API furar o limite do plano, e em silêncio**
>
> **Ignorar limites de recursos** vem **ligada de fábrica**, e o efeito foi medido
> dos dois lados, numa conta de teste com o limite de encaminhamentos de e-mail
> posto em **zero**:
>
> | Opção | O que a mesma criação respondeu |
> | - | - |
> | **desligada** | **400**, `The user does not have enough resources / permissions to perform this operation. Email forwardings limit exceeded.` |
> | **ligada**, que é o padrão | **201**, criado, com o limite continuando em zero |
>
> Para quem vende hospedagem por plano, isso é receita que escapa sem aviso, e
> nada no painel avisa que aconteceu. Se o seu sistema de vendas é quem controla
> o limite, ela pode continuar ligada de propósito. Se quem controla é o painel,
> desligue.

> [!WARNING]
>
> **A API não muda limite de cliente, e mente dizendo que mudou**
>
> Os limites de recursos são **somente leitura** na especificação da API. Medido:
> uma alteração de limite enviada pela API respondeu **200**, com o identificador
> do cliente, **e o limite continuou o mesmo**. Nenhum erro, nenhum aviso.
>
> Uma integração que tente ajustar plano de cliente por aqui vai achar que
> conseguiu. Limite se muda na tela do cliente, ou pelo pacote de contas.

> [!NOTE]
>
> **A política de senha desligada joga a responsabilidade para fora**
>
> Com **Aplique a política de senha** desmarcada, a API aceita qualquer senha, e
> a força dela passa a ser problema de quem chama. A tela diz isso com todas as
> letras. Ver [Política de Senha](/keyhelp-admin/politica-de-senha).

## Excluir uma chave

O ícone da lixeira na linha abre uma **tela de confirmação**, com o nome, o
prefixo, os IPs e a data de criação da chave, e uma caixa de **Confirmação** que
precisa ser marcada.

**Conferido:** com a caixa desmarcada, o navegador barra o envio e pede que ela
seja marcada. Depois de excluída, a chave **para de funcionar na mesma hora**: a
chamada seguinte volta com 401.

Há também **Ações em massa > Excluir seleção**, para tirar várias de uma vez.

## O que a coluna Último acesso conta, e o que não conta

**Ela registra o último uso que deu certo.** Medido: a chave que foi recusada por
IP continuou com o campo vazio depois da tentativa. Tentativa recusada não aparece
ali.

Ou seja, uma chave com **Último acesso** vazio pode estar sendo usada e recusada o
tempo todo. Para ver tentativa recusada, o lugar é o registro do servidor, não
esta tela.

## O que pode dar errado

| Sintoma | Causa | O que fazer |
| - | - | - |
| **403 com o texto `API is disabled.` em HTML** | o acesso da API está desligado nesta tela | ligar em **Acesso da API** |
| **401 dizendo que a chave é inválida, e você tem certeza que ela está certa** | o IP de quem chama não está na lista da chave | conferir a coluna **IPS** da chave, e o endereço de saída de quem consome |
| 401 com `API key is missing.` | o cabeçalho `X-API-Key` não foi enviado | conferir o nome do cabeçalho |
| 404 com `Endpoint not found.` | o caminho não existe nesta versão da API | conferir na especificação servida pelo próprio painel |
| 405 | o método HTTP não vale para aquele caminho | a própria resposta diz quais métodos valem |
| 406 | o `Accept` pede um formato que a API não faz | usar `application/json`, `application/xml` ou `text/yaml` |
| **Perdi a chave que tinha criado** | ela aparece uma única vez | criar outra e excluir a antiga. Não há recuperação |
| **Mudei limite de cliente pela API, veio 200, e o limite não mudou** | limite de recurso é somente leitura na API | mudar na tela do cliente, em **Administração do Usuário** |
| **Criei uma conta de e-mail pela API sem mandar senha, e veio uma senha na resposta** | o painel gera a senha quando ela não é enviada | tratar essa resposta como segredo: ela é a senha da caixa recém-criada |
| **A chave sumiu da lista sem ninguém excluir** | alguém importou configurações com o escopo de API marcado, e isso substitui a lista inteira | ver [Importar/Exportar as Configurações](/keyhelp-admin/importar-exportar-as-configuracoes), e criar a chave de novo |
| 500 ou 503 em chamada isolada, sem padrão | o painel recarrega o servidor web quando precisa, e a chamada pegou esse instante | repetir a chamada depois de alguns segundos, como a própria documentação do fabricante recomenda |

## Ver também

* [Política de Senha](/keyhelp-admin/politica-de-senha), a regra que a opção de senha da API liga ou desliga
* [Acesso e Sessão](/keyhelp-admin/acesso-e-sessao), que trata do acesso de pessoas, e não de programas
* [Importar/Exportar as Configurações](/keyhelp-admin/importar-exportar-as-configuracoes), cujo arquivo carrega as chaves de API para dentro
* [Limites e permissões do cliente](/keyhelp-admin/limites-e-permissoes-do-cliente), os limites que a opção padrão da API ignora


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