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.
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.
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.
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.
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.

