Pular para o conteúdo
mailchecker
  1. Início
  2. API

API v1

API de validação de e-mail

REST e JSON. Valide um endereço em tempo real, lotes de até 100 ou arquivos inteiros. Base: https://api.mailchecker.dev

Visão geral

Todas as rotas ficam em https://api.mailchecker.dev/v1, respondem JSON em UTF-8 (exceto o download de resultados, em CSV) e exigem uma chave de API. Crie e revogue chaves no portal, em API keys; a chave completa aparece uma única vez.

A especificação OpenAPI 3.1 fica em https://api.mailchecker.dev/v1/openapi.json.

Autenticação

Envie a chave (mc_live_…) no cabeçalho Authorization: Bearer ou, para compatibilidade com o ZeroBounce, no parâmetro api_key da query. Prefira o cabeçalho: URLs costumam parar em logs.

shell
# Cabeçalho (recomendado)
curl "https://api.mailchecker.dev/v1/credits" \
  -H "Authorization: Bearer mc_live_…"

# Ou na query, como no ZeroBounce
curl "https://api.mailchecker.dev/v1/credits?api_key=mc_live_…"

Endpoints

RotaPara quê
GET /v1/validateUm endereço, síncrono
POST /v1/validate/batchAté 100 endereços, síncrono
POST /v1/filesEnvia uma lista (CSV/XLSX)
GET /v1/files/{id}Progresso e totais da lista
GET /v1/files/{id}/downloadResultado da lista em CSV
GET /v1/creditsSaldo de créditos
GET /v1/usageUso por dia e status
GET /v1/openapi.jsonEspecificação OpenAPI 3.1
GET

/v1/validate?email=

Verifica um endereço e devolve um Verdict. Parâmetro: email (obrigatório).

requisição
curl "https://api.mailchecker.dev/v1/validate?email=joao.silva@gmail.com" \
  -H "Authorization: Bearer mc_live_…"
resposta · 200
{
  "address": "joao.silva@gmail.com",
  "status": "valid",
  "sub_status": "",
  "account": "joao.silva",
  "domain": "gmail.com",
  "did_you_mean": null,
  "free_email": true,
  "role_based": false,
  "disposable": false,
  "mx_found": true,
  "mx_record": "gmail-smtp-in.l.google.com",
  "smtp_provider": "google",
  "domain_age_days": 11318,
  "processed_at": "2026-11-07T12:34:56Z",
  "domain_score": 100,
  "domain_reasons": ["dmarc_none", "free_email"]
}
POST

/v1/validate/batch

Corpo {"emails": [...]} com até 100 endereços. Devolve um Verdict por endereço e o custo total do lote; repetidos no mesmo lote não são cobrados.

requisição
curl -X POST "https://api.mailchecker.dev/v1/validate/batch" \
  -H "Authorization: Bearer mc_live_…" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["ana@empresa.com.br", "joao@gmial.com"]}'
resposta · 200
{
  "results": [ /* um Verdict por endereço */ ],
  "cost": 2
}
POST

/v1/files

Multipart com file (CSV ou XLSX, até 1 milhão de linhas), column (opcional: a coluna do e-mail) e name. Responde 201 com a lista no estado queued.

requisição
curl -X POST "https://api.mailchecker.dev/v1/files" \
  -H "Authorization: Bearer mc_live_…" \
  -F "file=@clientes.csv" -F "column=2" -F "name=Clientes novembro"
GET

/v1/files/{id}

O estado da lista: uploaded, queued, running, done, failed ou cancelled, com os totais por status. Consulte de tempos em tempos até done.

resposta · 200
{
  "id": "0193f1c2-…",
  "name": "Clientes novembro",
  "original_filename": "clientes.csv",
  "state": "running",
  "total": 12480, "unique_count": 12011, "duplicates": 469,
  "processed": 8300,
  "counts": { "valid": 6904, "invalid": 811, "catch-all": 402, "unknown": 183 },
  "cost": 8117,
  "error": null,
  "created_at": "2026-11-07T12:00:00Z", "started_at": "2026-11-07T12:00:02Z", "finished_at": null
}
GET

/v1/files/{id}/download?filter=

O resultado em CSV. filter=all (padrão) traz tudo, valid só os válidos, no_invalid tudo menos os inválidos.

GET

/v1/credits

Saldo do time: {"balance": 1840}.

GET

/v1/usage?from=&to=

Uso diário por status, com datas AAAA-MM-DD: {"days": [{"day", "status", "count", "cost"}]}.

O resultado (Verdict)

Cada endereço verificado vira um objeto com estes campos:

CampoTipoDescrição
addressstringEndereço normalizado (sem espaços, domínio em minúsculas).
statusstringvalid, invalid, catch-all, unknown, spamtrap, abuse ou do_not_mail.
sub_statusstringDetalhe do status (lista abaixo); "" quando não há.
accountstringParte antes do @.
domainstringParte depois do @.
did_you_meanstring | nullCorreção sugerida para erro de digitação no domínio (gmial.com → gmail.com).
free_emailbooleanProvedor gratuito (Gmail, Outlook, Yahoo, UOL, BOL…).
role_basedbooleanEndereço de função: contato@, vendas@, suporte@…
disposablebooleanServiço de e-mail descartável/temporário.
mx_foundbooleanO domínio tem servidor de e-mail.
mx_recordstring | nullMX de maior prioridade.
smtp_providerstring | nullgoogle, microsoft, yahoo, proofpoint, mimecast, zoho, other…
domain_age_daysinteger | nullIdade do domínio em dias (RDAP).
processed_atstringData e hora da verificação, ISO 8601 (UTC).
domain_scoreinteger | nullReputação do domínio, 0–100 (maior = mais seguro), só de consultas DNS e de registro (RDAP), sem contato com o servidor de e-mail. Não altera o status. null quando não calculada.
domain_reasonsstring[]Motivos da pontuação, códigos estáveis em ordem fixa (lista abaixo).

Motivos da reputação do domínio

Cada motivo tira pontos de 100; os marcados "sem penalidade" são só informativos. Domínios de e-mail grátis (Gmail, Outlook…) só perdem pontos por blocklist.

CódigoSignificado
disposable_domaindomínio descartável
blocklist_spamhaus_dbllistado na Spamhaus DBL
blocklist_surbllistado na SURBL
blocklist_uribllistado na URIBL
blocklist_spamhaus_zenMX listado na Spamhaus ZEN
blocklist_barracudaMX listado na Barracuda
blocklist_unknownblocklist sem resposta (sem penalidade)
parked_domaindomínio estacionado ou à venda
null_mxdeclara que não recebe e-mail (MX nulo)
no_mxsem registro MX
mx_ip_literalMX é um IP, não um nome
mx_private_ipMX aponta para IP privado ou reservado
mx_no_addressservidor MX sem endereço IP
domain_age_lt_30ddomínio registrado há menos de 30 dias
domain_age_lt_1ydomínio registrado há menos de 1 ano
domain_age_unknownidade do domínio desconhecida (sem penalidade)
no_spfsem SPF
spf_invalidSPF inválido (mais de um registro)
spf_plus_allSPF permite qualquer remetente (+all)
no_dmarcsem DMARC
dmarc_noneDMARC só monitora (p=none)
free_emailprovedor de e-mail grátis (sem penalidade)
role_basedendereço de função (sem penalidade)

Status e sub-status

O mesmo vocabulário do ZeroBounce.

StatusSignificadoSub-status possíveis
valid A caixa existe e o servidor aceitou o destinatário. Pode enviar. —
invalid O endereço não recebe: caixa inexistente, domínio sem servidor de e-mail, erro de digitação ou sintaxe errada. Remova da lista: é o que gera bounce. mailbox_not_found, no_dns_entries, failed_syntax_check, possible_typo, unroutable_ip_address, does_not_accept_mail, mailbox_quota_exceeded, leading_period_removed
catch-all O domínio aceita qualquer endereço, então não dá para confirmar a caixa. Envie com cautela, de preferência em lotes menores. —
unknown O servidor não respondeu de forma conclusiva (greylisting, antispam, timeout). Não cobramos: tente de novo mais tarde. greylisted, antispam_system, mail_server_temporary_error, mail_server_did_not_respond, timeout_exceeded, failed_smtp_connection, forcible_disconnect, exception_occurred
do_not_mail O endereço existe, mas enviar é arriscado: e-mail descartável, de função (contato@, vendas@), tóxico ou em lista de supressão. role_based, disposable, toxic, global_suppression, role_based_catch_all, alias_address, mx_forward
spamtrap Provável armadilha de spam: um envio pode colocar seu domínio em blocklist. possible_trap
abuse Endereço conhecido por marcar mensagens como spam e denunciar remetentes. —

Erros

Todo erro vem no mesmo formato: um código estável em error, uma mensagem legível em message e, nos erros de validação, os campos com problema em fields.

resposta · 422
{
  "error": "validation",
  "message": "O campo email é obrigatório.",
  "fields": { "email": ["obrigatório"] }
}
HTTPerrorQuando
401unauthorizedChave ausente, inválida ou revogada.
402no_creditSaldo insuficiente. Numa lista, o processamento para com state=failed e error=no_credit.
422validationParâmetro faltando ou inválido; veja fields.
429rate_limitedLimite de requisições da chave excedido; aguarde e tente de novo.

Limites

  • Requisições: limite por chave, em balde de fichas (token bucket); o padrão é 10 requisições por segundo. Precisa de mais? Fale com a gente.
  • Lote síncrono: até 100 endereços por POST /v1/validate/batch.
  • Arquivos: CSV ou XLSX com até 1 milhão de linhas.
  • Retenção: resultados ficam disponíveis por 30 dias e depois são apagados (LGPD).

Cobrança

O débito acontece junto com a gravação do resultado: 1 crédito por endereço, inclusive catch-all. unknown custa 0 e endereços repetidos na mesma lista ou lote também. Consulte o saldo em GET /v1/credits e veja os preços.

Migrando do ZeroBounce

Desenhamos a API para que a migração seja curta:

  • Mesmos status e sub-status, com os mesmos nomes.
  • Mesmos nomes nos campos principais do resultado (address, status, sub_status, account, domain, did_you_mean, free_email, mx_found, mx_record, smtp_provider, domain_age_days, processed_at).
  • Chave aceita em ?api_key=.
  • Mesmas regras de cobrança: unknown e duplicatas não cobram.
antes e depois
# ZeroBounce
GET https://api.zerobounce.net/v2/validate?api_key=SUA_CHAVE&email=ana@empresa.com.br

# mailchecker: troque a base e a chave
GET https://api.mailchecker.dev/v1/validate?api_key=mc_live_…&email=ana@empresa.com.br

O que muda: a URL base e o caminho (/v1/...), a chave, e os campos de nome, gênero e localização, que não existem nesta versão. Adicionamos role_based e disposable como booleanos. Confira os tipos dos campos no seu parser antes de trocar em produção.

Veja também a comparação completa.