Três endpoints, JSON na entrada e na saída. Sem chave e sem conta em domínios
públicos — cole uma requisição em um terminal e funciona.
Visão geral
Uma caixa de entrada nunca é criada — ela existe no momento em que uma
mensagem chega a um endereço, e desaparece 5 dias depois. Não há
nada para registrar, então nos domínios públicos a API não tem conceito de
usuário, projeto ou token.
Toda resposta é JSON, incluindo todo erro.
Todos os horários são UTC no formato RFC 3339 — 2026-08-04T18:31:07Z.
Os ids de mensagem são strings opacas. Não tente interpretá-los.
Somente recebimento. Não há endpoint que envie e-mail, por design.
URL base
https://grabmail.io/api/v1
Apenas HTTPS; HTTP puro é redirecionado. A versão fica no caminho, e
v1 não vai mudar de forma sob você — uma mudança que quebre
compatibilidade ganha um novo número.
Autenticação
Nenhuma nos domínios públicos. Qualquer pessoa que conheça
um endereço pode ler sua caixa de entrada, tanto pela API quanto pelo site.
Esse é o acordo que um serviço descartável compartilhado propõe, então nunca
use um endereço público para algo que importa.
Em um domínio que você possui, a caixa de entrada é privada, então as
requisições levam uma chave — que é o que prova que a caixa é sua. A chave
é emitida quando você verificar o domínio, mostrada uma única vez,
e armazenada aqui só como hash:
Authorization: Bearer <your key>
Chave errada ou ausente em um domínio privado responde 401 com
unauthorized. As chaves são comparadas em tempo constante,
então uma errada leva o mesmo tempo para ser rejeitada que uma certa leva
para ser aceita.
Endpoints
GET/api/v1/mailbox
Tudo o que está esperando em um endereço, do mais novo ao mais antigo. Esta é a chamada que seu conjunto de testes consulta repetidamente.
Parâmetros
Nome
Em
Tipo
Obrigatório
Descrição
address
query
string
sim
A caixa de entrada a ser lida, ex.: k7fq2m@grabmail.io.
limit
query
integer
não
Quantas mensagens retornar nesta chamada, 1–200. O padrão é 50, mais recentes primeiro. Isso limita uma resposta, não a caixa de entrada — use before para ler além dela.
before
query
string
não
O id da mensagem mais antiga que você já tem; retorna a página seguinte a ela. Devolva o campo next da resposta anterior. Quando next for null, você tem tudo.
A caixa de entrada foi lida. Uma caixa de entrada vazia é um 200 com count: 0, nunca um 404. next carrega o cursor para a página seguinte, ou null no final.
400
O endereço está malformado, ou before não é um id de mensagem.
400
address está ausente ou não é um endereço válido.
404
Esse domínio não é hospedado aqui — verifique o registro MX.
429
Limite de requisições excedido. Tente novamente após o atraso em Retry-After.
GET/api/v1/message/{id}
Cabeçalhos, a parte em texto simples, a parte em HTML e quaisquer anexos.
Parâmetros
Nome
Em
Tipo
Obrigatório
Descrição
id
path
string
sim
O id de mensagem retornado pela chamada de listagem.
Excluído. A chamada é idempotente: excluir duas vezes ainda responde 200.
400
mailbox está ausente ou é inválido.
404
Nenhuma mensagem encontrada nessa caixa de entrada.
429
Limite de requisições excedido.
Anexos
Toda mensagem lista seus anexos com uma URL pronta. Baixe-o com a mesma
autorização usada para a mensagem em si.
GET /api/v1/attachment/{id}?mailbox={address}
Ele sempre responde application/octet-stream com
Content-Disposition: attachment, seja qual for o rótulo do
remetente. Isso é proposital: devolver o text/html de um
estranho permitiria que um anexo rodasse como página nesta mesma origem. O
tipo real está no JSON da mensagem, onde é dado, não instrução.
Erros
Toda falha é um JSON com os mesmos dois campos, então um cliente trata
todas em um único lugar. O status carrega a categoria, error é
um identificador estável e legível por máquina, e message é
para humanos e pode mudar de texto a qualquer momento.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_address",
"message": "address must look like name@domain"
}
Nunca decida com base em message. Os identificadores em uso
são invalid_address, unknown_domain,
not_found e rate_limited.
Limites de taxa
Uma requisição por segundo, por endereço. Consultar uma
caixa de entrada uma vez por segundo é o padrão previsto e nunca é limitado.
Acima do limite você recebe 429 com Retry-After
em segundos. Não há cota diária nem crédito de rajada para gerenciar.
Retenção
Uma mensagem é apagada 5 dias
depois de chegar, lida ou não. Toda mensagem traz
expires_at, então você nunca precisa calcular essa data.
É um limite fixo, não uma configuração — nenhum parâmetro o estende. Se uma
mensagem precisa sobreviver além dessa janela, busque-a e guarde-a do seu
lado.
Seu próprio domínio
Aponte seu MX para smtp.grabmail.io e todo endereço do
seu domínio passa a responder por estes mesmos endpoints — nenhuma segunda
API para aprender, e as caixas de entrada só são legíveis com sua chave.