Referência da API

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

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.

Um domínio que você aponta para cá responde nesses mesmos endpoints, também sem chave. Aponte o MX para nós e a primeira mensagem o conecta; veja conectar um domínio. As caixas de entrada nele podem ser lidas por qualquer um que conheça o endereço, exatamente como nos domínios públicos.

Um caso ainda exige um cabeçalho: um domínio que fechamos a pedido é lido com Authorization: Bearer <chave>, e uma chave errada ou ausente responde 401 com unauthorized. As chaves são comparadas em tempo constante, então uma errada demora tanto para ser rejeitada quanto uma certa para ser aceita.

Domínios premium

A única exceção à regra acima. Os domínios públicos constam das listas públicas de correio descartável, e por isso um formulário de registo recusa por vezes um endereço neles alojado. Um plano pago abre um pool de 92 domínios .com privados, fora dessas listas.

A API não muda em nada. Mesmos caminhos, mesmos parâmetros, mesmos formatos de resposta. A única diferença é um cabeçalho: um endereço premium lê-se com Authorization: Bearer gm_live_…, com uma chave de as suas chaves de API. Sem uma chave válida, o mesmo pedido responde 402 ou 403 — nunca uma caixa.

# A public domain: no header at all.
curl -sG https://grabmail.io/api/v1/mailbox \
  --data-urlencode "address=a7f3k2@grabmail.io"

# A premium domain: the same call, plus a key.
curl -sG https://grabmail.io/api/v1/mailbox \
  -H "Authorization: Bearer gm_live_…" \
  --data-urlencode "address=a7f3k2@one-of-the-pool.com"

Os domínios públicos e os seus próprios domínios continuam gratuitos, sem chave e sem limite em todos os planos, incluindo o gratuito. As quotas contam apenas as mensagens que chegam ao pool premium. Os planos e os preços estão em a página dos planos.

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

NomeEmTipoObrigatórioDescriçã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.

Exemplo

Listar uma caixa de entrada
$ curl -G https://grabmail.io/api/v1/mailbox \
  --data-urlencode "address=k7fq2m@grabmail.io"

{
  "address": "k7fq2m@grabmail.io",
  "count": 1,
  "next": null,
  "messages": [
    {
      "id": "01JR8W2K4Q",
      "from": "no-reply@example.com",
      "subject": "Your verification code",
      "date": "2026-08-04T18:31:07Z",
      "seen": false,
      "attachments": 0,
      "expires_at": "2026-08-09T18:31:07Z"
    }
  ]
}

Códigos de status

200
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

NomeEmTipoObrigatórioDescrição
id path string sim O id de mensagem retornado pela chamada de listagem.
mailbox query string sim O endereço para o qual a mensagem foi entregue.

Exemplo

Ler uma mensagem
$ curl -G https://grabmail.io/api/v1/message/01JR8W2K4Q \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"

{
  "id": "01JR8W2K4Q",
  "from": "no-reply@example.com",
  "to": "k7fq2m@grabmail.io",
  "subject": "Your verification code",
  "date": "2026-08-04T18:31:07Z",
  "text": "Your code is 481920. It expires in 10 minutes.",
  "html": null,
  "attachments": []
}

Códigos de status

200
A mensagem. html é null quando o remetente enviou apenas texto simples.
400
mailbox está ausente ou é inválido.
404
Nenhuma mensagem encontrada nessa caixa de entrada — ou ela passou da janela de retenção.
429
Limite de requisições excedido.
DELETE /api/v1/message/{id}

Remove imediatamente, em vez de esperar a janela de retenção expirar.

Parâmetros

NomeEmTipoObrigatórioDescrição
id path string sim A mensagem a ser removida.
mailbox query string sim O endereço para o qual foi entregue.

Exemplo

Excluir uma mensagem
$ curl -X DELETE -G https://grabmail.io/api/v1/message/01JR8W2K4Q \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"

{
  "deleted": true,
  "id": "01JR8W2K4Q"
}

Códigos de status

200
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 responde por esses mesmos endpoints — sem uma segunda API para aprender, sem registro e sem chave.

Conectar um domínio →

Bem-vindo de volta

As suas caixas e os seus domínios, num só lugar.