Documentação Maildo

Autenticação e requisições

Como usar sessão segura, CSRF e idempotência com o contrato real da API Maildo.

Sessão de navegador

O fluxo de login começa em GET /v1/auth/login, na aplicação, e redireciona para o provedor de identidade. O retorno é gerenciado pelo servidor. Não acrescente uma URL de retorno arbitrária nem coloque credenciais em parâmetros.

A sessão usa cookie Secure, HttpOnly e SameSite=Lax, restrito ao host. Scripts não devem ler ou persistir o cookie. A duração é limitada e pode expirar antes de você terminar uma operação.

GET /v1/auth/config

Consulta pública. Retorna data.enabled e os caminhos de login, sessão e logout. enabled não significa que um workspace já está aprovado.

GET /v1/auth/session

Consulta a identidade autenticada. Retorna data.authenticated, data.email e data.expiresAt; o cabeçalho X-CSRF-Token fornece a proteção para escritas. Com autenticação de navegador habilitada, uma sessão ausente ou inválida retorna 401; com essa autenticação desabilitada, a rota retorna 404.

GET /v1/session

Consulta a autorização operacional. Retorna actorId, role, workspaceId, mode, storage e liveSendingEnabled dentro de data. A identidade verificada não substitui a autorização de workspace.

POST /v1/auth/logout

Invalida a sessão local do Maildo. Exige Origin da aplicação e X-CSRF-Token, mas não exige corpo JSON ou Idempotency-Key. Não encerra automaticamente a sessão SSO do provedor.

Cookies, origem e CSRF

Faça as requisições no mesmo host da aplicação, com credentials: 'same-origin'. Em escritas, envie o X-CSRF-Token obtido de um GET autenticado. O navegador fornece o cabeçalho Origin. Origem incompatível é recusada; este site público não é um cliente cross-origin da API.

Uma integração Bearer usa exclusivamente um access token OIDC válido para o emissor e a audiência da API, sem cookie. Não use ID token, JWT arbitrário ou uma suposta chave de API. Misturar cookie e Authorization retorna 400 authentication_conflict. Tokens não devem ir para URL, localStorage ou repositório.

Exemplo de leitura autenticada

// Execute somente dentro da aplicação autenticada em app.maildo.com.br.
// Este exemplo é de leitura; não envie cookies ou tokens para outro domínio.
const identityResponse = await fetch('/v1/auth/session', {
  credentials: 'same-origin'
});
if (!identityResponse.ok) throw new Error('Entre novamente na plataforma.');
const identity = (await identityResponse.json()).data;
const csrfToken = identityResponse.headers.get('X-CSRF-Token');

const sessionResponse = await fetch('/v1/session', {
  credentials: 'same-origin'
});
if (!sessionResponse.ok) throw new Error('Workspace ainda não autorizado.');
const session = (await sessionResponse.json()).data;

const response = await fetch('/v1/workspace/contacts?limit=50&offset=0', {
  credentials: 'same-origin'
});
if (!response.ok) throw new Error('Não foi possível consultar os contatos.');
const { items, nextOffset } = (await response.json()).data;
// nextOffset === null encerra a paginação. Não exponha os dados no site público.

O exemplo pressupõe uma sessão já estabelecida na aplicação e um workspace autorizado. Não há botão para executá-lo aqui. Não copie uma sessão para outro domínio.

Formato das respostas e paginação

Sucesso HTTP 200:
{"data":{"items":[],"nextOffset":null}}

Falha:
{"error":{"code":"forbidden","message":"Acesso não autorizado."}}

Os sucessos JSON de criação e enfileiramento também usam HTTP 200. Coleções paginadas retornam items e nextOffset dentro de data. Use limit de 1 a 100 (padrão 50) e offset a partir de zero. Siga o próximo offset retornado até receber null.

Campos desconhecidos são rejeitados. O papel viewer é somente leitura. Não envie X-Workspace-Id ou X-Tenant-Id: a identidade do workspace é resolvida no servidor.

Escritas e resultado incerto

Escritas JSON exigem Content-Type: application/json e Idempotency-Key, além de CSRF nas sessões com cookie. A exceção de logout está descrita acima. Use um UUID gerado uma vez para cada intenção; mantenha a mesma chave apenas para repetir a mesma operação com o mesmo corpo.

A mesma chave com conteúdo diferente pode retornar 409. Não gere uma chave nova automaticamente após timeout ou falha de rede: o servidor pode ter processado a primeira chamada. Consulte o recurso e preserve o contexto antes de decidir por uma nova tentativa.

401 indica necessidade de autenticação; 403 indica permissão ou proteção de requisição; 409 pode indicar conflito de versão ou de idempotência. 503 pode indicar serviço não habilitado. Nunca converta uma falha em sucesso presumido.