Email Spam Tester

API de teste de spam: e-mail,
caixa de entrada e domínio

Envie-nos uma mensagem real ou indique-nos apenas um domínio. Tudo responde em JSON.

Sem chave, sem conta.

Pedido

# reserve a single-use address

$ curl -sX POST '.../api/v1/inbox?lang=en'

# send your message to that address, then

$ curl -s '.../api/v1/tests/k7m2x9qplw4tz8vn3b6c/status'

# read the report

$ curl -s '.../api/v1/tests/k7m2x9qplw4tz8vn3b6c'

Resposta

200 OK

{
  "address": "test-k7m2x9qplw4tz8vn3b6c@t.email-spam-tester.com",
  "slug": "k7m2x9qplw4tz8vn3b6c",
  "expires_at": "2026-10-31T13:00:00Z"
}

200 OK

{
  "analysis_status": "checks_ready",
  "ai_status": "running",
  "checks_done": 42,
  "checks_total": 42
}

200 OK

{
  "score_ours": 86.4,
  "score_compat": 9.2,
  "subscores": {"auth": 100.0, "infra_spam": 78.1, "content": 92.0},
  "complete": true,
  "checks": [{"id": "auth.dmarc", "status": "warn"}],
  "fixes": [{"id": "dmarc-enforce", "gain_ours": 4.0}]
}

Pedido

# create a test

$ curl -sX POST '.../api/v1/placement' \ -d '{"public_results_accepted":true}'

# put the marker in the subject, send once to all, then

$ curl -s '.../api/v1/placement/wR3kP9xLq2vT8mZc'

Resposta

201 Created

{
  "marker": "est-3f9a1c7e2b4d6a80c5e1f2d3",
  "status": "waiting",
  "results": [{"provider": "gmail", "placement": "pending"}],
  "fleet": {"status": "observing", "results": [
    {"provider": "yahoo", "placement": "pending"},
    {"provider": "outlook", "placement": "pending"}
  ]}
}

200 OK

{
  "status": "complete",
  "results": [{"provider": "gmail", "placement": "primary"}],
  "fleet": {"status": "finished", "results": [
    {"provider": "yahoo", "placement": "inbox"},
    {"provider": "outlook", "placement": "spam"}
  ]}
}

Pedido

# no email needed, one GET

$ curl -s '.../api/v1/infra/check?domain=example.com'

# compare with your last run

$ curl -s '.../api/v1/infra/check?domain=example.com&diff=true' \ | jq '.diff'

Resposta

200 OK

{
  "domain": "example.com",
  "ok": false,
  "status": "fail",
  "score": 78,
  "coverage": {"answered": 7, "total": 8},
  "sections": {"ptr": {"status": "fail", "core": true}}
}

200 OK

{
  "changed": true,
  "worsened": true,
  "status_from": "pass",
  "score_from": 100,
  "changes": [{"path": "dkim.key.mail.sha256", "kind": "removed",
               "severity": "critical", "effect": "worsened"}]
}
Nesta página

Teste de email

Lemos uma mensagem real do início ao fim: conteúdo, assinatura, cabeçalhos e o servidor que a enviou. Você recebe uma pontuação, uma lista de correções e todas as verificações subjacentes.

Início rápido

Três chamadas. Sem chave, sem conta, sem registo. Dois pedidos e um email. A terceira chamada só existe porque a análise demora alguns segundos.

  1. Reserve um endereço

    Faça um POST para o endpoint da caixa de entrada. Recebe um endereço que aceita exatamente uma mensagem e expira ao fim de uma hora, bem como o slug ao qual tudo o resto está associado.

    Pedido

    # 1. reserve a single-use address
    curl -sX POST 'https://email-spam-tester.com/api/v1/inbox?lang=en'

    Resposta

    {
      "address": "test-<slug>@t.email-spam-tester.com",
      "slug": "<slug>",
      "expires_at": "2026-01-01T12:00:00Z"
    }
  2. Envie-lhe a mensagem real

    Através de SMTP, a partir da plataforma que enviará a campanha. Metade das verificações lê os cabeçalhos adicionados pela sua plataforma de envio, pelo que uma mensagem composta manualmente avalia a coisa errada.

    Pedido

    # 2. send your message to that address, from your own platform
    To: test-<slug>@t.email-spam-tester.com
  3. Consulte o estado e depois leia o relatório

    O endpoint de estado tem algumas centenas de bytes e indica se já vale a pena obter o relatório completo. O relatório propriamente dito tem vários milhares de linhas.

    Pedido

    # 3. poll
    curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>/status'

    Resposta

    {
      "slug": "<slug>",
      "analysis_status": "checks_ready",
      "ai_status": "running",
      "checks_done": 42,
      "checks_total": 42
    }

    Pedido

    # 4. read the report once analysis_status is checks_ready
    curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>'

    Resposta

    {
      "report_url": "https://email-spam-tester.com/t/<slug>",
      "score_ours": 86.4,
      "score_compat": 9.2,
      "subscores": {"auth": 100.0, "infra_spam": 78.1, "content": 92.0, "compliance": 75.0},
      "complete": true,
      "checks": [
        {
          "id": "auth.dmarc",
          "status": "warn",
          "title": "DMARC result",
          "summary": "DMARC passes, but the policy is p=none.",
          "weight_ours": -4.0,
          "evidence": {"policy": "none", "aligned": "dkim"},
          "citations": {"standards": [{"title": "RFC 9989 §4.7", "quote": "..."}]}
        }
      ],
      "fixes": [
        {"id": "dmarc-enforce", "gain_ours": 4.0, "gain_compat": 0.0,
         "fix": {"title": "Move DMARC to quarantine", "severity": "medium"}}
      ]
    }

Reserve um endereço, envie a mensagem que estava prestes a enviar à sua lista e consulte o relatório. Tudo o que a página apresenta está no JSON, incluindo a pontuação, as 42 verificações com as respetivas evidências e a secção da norma em que se baseia cada resultado.

Os primeiros 100 000 relatórios são gratuitos, sem chave e sem conta. Se estiver a configurar um agente em vez de um script, o servidor MCP é mais adequado do que fazer consultas periódicas.

Endpoints

Endereço base https://email-spam-tester.com. Tudo responde em JSON.

POST/api/v1/inbox

Reserva um endereço de utilização única. Ambos os parâmetros são opcionais.

langIdioma em que serão escritos o plano de correção e as conclusões de cada verificação, como código ISO. É decidido agora porque a mensagem chega por SMTP minutos mais tarde e não contém qualquer indicação de quem está à espera dela. Um código desconhecido usa inglês como alternativa.
utm_source, utm_medium, utm_campaignTransmitidos para as nossas análises. Útil se estiver a medir a sua própria integração.

GET/api/v1/tests/{slug}/status

Pouco dispendioso de consultar. Devolve os dois campos de estado e o progresso das verificações, e nada mais.

Consulte este endpoint em vez do relatório. analysis_status atinge primeiro checks_ready, e o plano de AI fica disponível em ai_status cerca de um minuto mais tarde, para que um cliente que apenas pretenda as verificações determinísticas não tenha de esperar pelo plano.

GET/api/v1/tests/{slug}

O relatório completo. Responde com 202 enquanto o endereço está reservado e ainda não chegou nada, e com 200 assim que chegar.

GET/api/v1/tests/{slug}/message

A mensagem exatamente como foi entregue: todos os cabeçalhos pela ordem de transmissão, ambos os corpos, a lista de anexos e a fonte em bruto. É obtida separadamente porque o relatório é consultado repetidamente e esta mensagem pode atingir um megabyte.

A mensagem em bruto é eliminada segundo o seu próprio prazo, antes do relatório. Depois disso, este endpoint responde com o motivo em vez do conteúdo original.

PUT/api/v1/tests/{slug}/locale

Altera o idioma de uma reserva que ainda não foi utilizada. Para um agente que descobre qual o idioma que o utilizador lê depois de já ter pedido o endereço. Recusado assim que a mensagem chega, porque nessa altura a análise já está em curso.

Colocação na caixa de entradaBeta

Envie uma mensagem para uma lista de caixas de entrada de teste e veja onde ficou no Gmail, Outlook, Yahoo e noutros fornecedores: Caixa de entrada, Promoções ou Spam.

Início rápido

  1. Crie um teste

    Faça um POST para o endpoint de colocação. Receberá um marcador e as caixas de correio de teste.

    Pedido

    # 1. create a test
    curl -sX POST 'https://email-spam-tester.com/api/v1/placement' \
      -H 'Content-Type: application/json' \
      -d '{"public_results_accepted":true}'

    Resposta

    {
      "slug": "<slug>",
      "marker": "est-3f9a1c7e2b4d6a80c5e1f2d3",
      "status": "waiting",
      "deadline": "2026-10-31T12:30:00Z",
      "poll_after_seconds": 60,
      "results": [
        {"address": "<seed>", "provider": "gmail", "kind": "Gmail",
         "placement": "pending", "observed_at": null}
      ],
      "fleet": {
        "status": "observing",
        "results": [
          {"address": "<mailbox>", "provider": "yahoo", "available": true,
           "placement": "pending", "coverage": "pending"}
        ]
      }
    }
  2. Envie uma mensagem para cada caixa de correio

    Coloque o marcador no assunto e envie a partir da sua plataforma habitual, para todos os endereços de uma só vez.

    Pedido

    # 2. one message to every address, with the marker in the subject
    Subject: October invoice est-3f9a1c7e2b4d6a80c5e1f2d3
    To: <seed>, <mailbox>, ...
  3. Consulte as pastas

    Cada endereço é preenchido com o respetivo fornecedor e pasta. Consulte repetidamente até o estado deixar de ser waiting.

    Pedido

    # 3. poll for the folders
    curl -s 'https://email-spam-tester.com/api/v1/placement/<slug>'

    Resposta

    {
      "status": "complete",
      "received": 2,
      "total": 2,
      "results": [
        {"address": "<seed>", "provider": "gmail", "kind": "Gmail",
         "placement": "primary", "observed_at": "2026-10-31T12:04:11Z"},
        {"address": "<seed>", "provider": "gmail", "kind": "Google Workspace",
         "placement": "promotions", "observed_at": "2026-10-31T12:04:11Z"}
      ],
      "fleet": {
        "status": "finished",
        "results": [
          {"address": "<mailbox>", "provider": "yahoo", "available": true,
           "placement": "inbox", "coverage": "ok"},
          {"address": "<mailbox>", "provider": "outlook", "available": true,
           "placement": "spam", "coverage": "ok"}
        ]
      }
    }

Endpoints

An optional test using public GMass seed inboxes and available project test mailboxes, alone or alongside the email score. Explain to the sender that GMass receives their email and publishes its subject, sender name and placement before creating a test. Use all test mailboxes for non-confidential test messages only.

GET /api/v1/placement/availability

Returns providers: the provider identifiers of currently healthy, admitted project mailboxes. No addresses or credentials are exposed. This read does not create a test or contact GMass. Actual recipients are allocated at creation and may differ as availability or capacity changes.

POST /api/v1/placement

Send JSON {"public_results_accepted":true}. Returns HTTP 201 with slug, marker, results (the seed addresses), deadline and expires_at. Limit: 20 tests per IP per UTC day.

For one-send combined testing, first reserve an email score address and include its score_slug in the placement creation JSON. Repeated creation for that score returns the same placement test. Send the marked email to the score address, every returned seed and every available fleet.results address; keep the main /t/<score_slug> report link. Creating a link after the score address was used or expired returns HTTP 409.

GET /api/v1/placement/by-score/{score_slug}

Read and refresh the placement run attached to the main email test. The response has the same format and polling limits as the standalone endpoint below. HTTP 404 means placement was not included or its stored results have been removed.

GET /api/v1/placement/{slug}

Use poll_after_seconds (normally 60 seconds) while the page is open. Upstream errors trigger a shared cooldown. Add the marker to the subject and send through the sender's normal platform to every seed. Observations are saved for 30 days. Collection ends after 30 minutes or when all seeds have results.

status: waiting, complete or timed_out. Each result has an address, provider, kind, placement and observed_at. Placement is primary, promotions, inbox, updates, social, forums, spam, unknown, pending or not_observed. Missing results do not mean Spam; Promotions is an inbox category. provider_error indicates an upstream outage without discarding saved observations. HTTP 404 means unknown, 410 expired, 429 quota exhausted, and 503 no test inboxes available at creation.

The optional fleet object contains independently collected project mailbox results, with status observing, settling or finished. Refresh every 30 seconds until it finishes, even when Gmail has completed. Each fleet result includes address, provider, available, placement, category and coverage. Exclude unavailable addresses from new sends; retain their saved observations. Category data may be unavailable even when the physical folder is known.

If GMass is unavailable at creation but project mailboxes can be allocated, provider is fleet and the top-level seed results are empty. Use fleet.results; do not interpret an empty Gmail list as successful delivery. Existing runs never gain new recipient addresses silently.

Verificação da infraestrutura

Um pedido GET verifica a configuração de correio de um domínio sem enviar nada, guarda o resultado e indica-lhe o que mudou desde a última execução. Não é necessária nenhuma chave. Em cron, a linha abaixo termina com um código diferente de zero quando o domínio está danificado ou a respetiva configuração mudou de uma forma relevante.

Início rápido

  1. Faça um GET

    Indique o domínio. ip adiciona os seus endereços de envio e selector indica os seletores DKIM a consultar.

    Pedido

    curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true'
  2. Leia o veredicto

    ok é a resposta para um script e sections mostra a parte que falhou.

    Resposta

    {
      "id": "ir_01JB8Y4T2M6K9QZ7H3V5N1XWDA",
      "domain": "example.com",
      "checked_at": "2026-10-31T12:00:00Z",
      "ok": false,
      "status": "fail",
      "score": 78,
      "coverage": {"answered": 7, "total": 8},
      "ips": [{"ip": "203.0.113.5", "sources": ["mx", "spf"], "managed": false}],
      "sections": {
        "dkim": {"status": "pass", "core": true, "findings": [], "data": {}},
        "ptr": {"status": "fail", "core": true, "findings": [], "data": {}}
      },
      "not_checked": [
        {"check": "dkim_signature", "reason": "needs_a_message"},
        {"check": "alignment", "reason": "needs_a_message"}
      ],
      "diff": {
        "baseline": {"id": "ir_01JB2...", "checked_at": "2026-10-24T12:00:00Z"},
        "first_run": false,
        "changed": true,
        "worsened": true,
        "status_from": "pass",
        "score_from": 100,
        "changes": [
          {"path": "dkim.key.mail.sha256", "section": "dkim", "kind": "removed",
           "severity": "critical", "effect": "worsened", "from": "9f2c...", "to": null}
        ],
        "not_compared": [
          {"path": "blocklist_ip.203.0.113.5.bl.spamcop.net.listed", "reason": "lookup_failed"}
        ]
      }
    }
  3. Coloque-o no cron

    Com diff=true, cada execução é comparada com a última e jq transforma a resposta num código de saída.

    Pedido

    # exits non-zero if the domain is broken or its setup changed
    curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true' \
      | jq -e '.ok and (.diff.changed | not)'
domainObrigatório. Aceita o mesmo que as ferramentas: um domínio, um URL, um endereço de email.
ipO seu endereço de envio. Repita-o para adicionar mais, até 6.
selectorUm seletor DKIM. Repita-o para adicionar mais, até 10. Cada seletor que enviar tem de existir, ou a secção dkim falha.
heloO nome que o seu servidor fornece em HELO, comparado com o respetivo PTR.
accountA quem se destina o pedido. Obrigatório com uma chave que serve várias pessoas.
checksSecções a executar, separadas por vírgulas. Todas por predefinição.
difftrue compara esta execução com a sua última execução do domínio.
since7d, 12h ou uma data ISO 8601. Compara com a sua execução mais próxima desse momento num intervalo de 12 horas; caso contrário, com a última anterior. Ativa diff.
baselineO ID de uma das suas execuções com a qual comparar. Ativa diff.
freshtrue ignora a cache de 60 segundos.

Ler a resposta

Uma verificação concluída responde com 200, e o veredito encontra-se no corpo. status é o pior resultado das secções obrigatórias: spf, dkim, dmarc, ptr, blocklist_ip, blocklist_domain, mx e smtp. unknown numa secção obrigatória conta como warn. ok é true quando status é pass ou warn. score varia entre 0 e 100 nas secções obrigatórias que responderam, e é null quando os erros e os estados unknown deixam menos de metade do peso aplicável. mta_sts, tls_rpt, bimi, dnssec, dane, ns e registration são apresentados e comparados, mas não afetam ok nem score.

Uma secção pode ser pass, warn, fail, error (não foi possível verificar), unknown (informação insuficiente) ou skipped (não se aplica). skipped não afeta o resultado, e o motivo encontra-se em not_checked. dkim_signature e alignment estão sempre presentes, porque precisam de uma mensagem real.

O que ip e selector alteram

PTR e as listas de bloqueio dizem respeito a endereços, pelo que uma execução precisa de alguns. Utiliza os valores de ip que você fornece. Se não fornecer nenhum, obtém até quatro dos seus anfitriões MX e dos termos ip4: e ip6: de endereço único no registo SPF raiz. Os endereços de um fornecedor de correio conhecido são indicados como managed e não são verificados, e, se não restar nenhum, ptr e blocklist_ip respondem com skipped. Um selector não pode ser lido a partir do DNS, pelo que uma execução tenta o seu, os que as suas execuções anteriores encontraram e uma lista de nomes comuns. Não encontrar nenhum não prova nada, e dkim responde com unknown. Se você enviar a partir do seu próprio servidor, forneça ambos.

O que mudou

Cada entrada em diff.changes tem um path, um kind (added, removed, changed), uma severity (critical, warning, info) e um effect (worsened, improved, neutral). Apenas critical e warning definem diff.changed, pelo que uma chave DKIM substituída por outra do mesmo comprimento, um novo endereço MX ou um certificado renovado não fazem com que a linha cron falhe. diff.worsened reflete o efeito de qualquer alteração. Numa primeira execução, não há nada com que comparar, e diff.first_run indica-o.

Uma referência é sempre uma execução sua, pelo que outra pessoa verificar o domínio entre duas das suas execuções não oculta nada. Tudo o que não foi possível ler desta vez vai para diff.not_compared, mantendo o último valor conhecido, o que significa que uma alteração feita durante uma indisponibilidade aparece assim que a consulta voltar a funcionar. Uma execução com um ip ou selector diferente permanece na mesma série, e o que não pediu também não é comparado.

Por que uma verificação agendada deve usar uma chave

Sem uma chave, o seu histórico pertence a um hash com chave do seu endereço IP, pelo que termina quando o endereço muda, e as pessoas que partilham um endereço também partilham o histórico: a execução de um colega altera a sua referência. Com uma chave de API pessoal em Authorization: Bearer, o histórico fica associado à chave. As execuções com uma chave são mantidas durante 365 dias e só podem ser consultadas com essa chave. As execuções sem chave são mantidas durante 30 dias e podem ser consultadas por qualquer pessoa que tenha o respetivo id.

6 pedidos por minuto e 50 por dia por IP, ou 30 e 500 por chave. Acima desse limite, a resposta é 429 com Retry-After. Um pedido idêntico no espaço de 60 segundos vem de uma cache, é marcado como cached: true, não regista nenhuma execução e não conta. A leitura de execuções armazenadas permite 120 pedidos por minuto por cliente. 503 com Retry-After significa que estão a ser executadas demasiadas verificações ou, ao ler execuções armazenadas, que o armazenamento está indisponível. 401 indica uma chave incorreta. 422 inclui detail.code: invalid_domain, invalid_ip, invalid_selector, invalid_check, invalid_since, unknown_baseline ou account_required.

Endpoints

GET/api/v1/infra/check

Executa a verificação. Os parâmetros estão na tabela acima.

GET/api/v1/infra/runs/{public_id}

Uma execução armazenada, completa. 404 se não existir ou pertencer a outra chave.

GET/api/v1/infra/domains/{domain}/runs

As suas execuções de um domínio, da mais recente para a mais antiga: id, hora, estado, pontuação e número de alterações. Aceita limit (1 a 100, 30 por predefinição) e before, um id de execução.

GET/api/v1/infra/diff

A mesma comparação entre duas execuções armazenadas, ?from=<id>&to=<id>. Você precisa de acesso a ambas.

GET/api/v1/infra/checks

Todas as secções com o respetivo peso, a versão da pontuação e os limites.

Verificações individuais

Cada chamada responde a uma pergunta e não mantém histórico. Uma ferramenta executa autonomamente uma parte da verificação da infraestrutura, exceto a ferramenta de cabeçalhos, que lê uma mensagem que você já recebeu.

Início rápido

  1. Escolha uma verificação

    Escolha a ferramenta na lista abaixo e indique o domínio, o endereço ou o IP solicitado.

    Pedido

    curl -s 'https://email-spam-tester.com/api/v1/tools/spf?domain=example.com'
  2. Leia o estado e as conclusões

    Cada ferramenta responde com um estado e as respetivas conclusões. Os campos seguintes dependem da ferramenta.

    Resposta

    {
      "tool": "spf",
      "query": {"domain": "example.com"},
      "checked_at": "2026-10-31T12:00:00Z",
      "duration_ms": 412,
      "status": "fail",
      "findings": [
        {"code": "spf.too_many_lookups", "level": "fail",
         "params": {"limit": 10, "count": 12},
         "message": "RFC 7208 §4.6.4 allows at most 10 DNS lookups, and this record needs 12, so receivers return permerror."}
      ],
      "record": "v=spf1 include:_spf.example.net ~all",
      "lookups": {"count": 12, "limit": 10, "void": 0}
    }

Endpoints

Todos respondem com 200, um estado e uma lista de resultados, cada um com um código e os respetivos parâmetros. O estado é pass, warn, fail ou error, e uma ferramenta partilhada com a verificação da infraestrutura também pode responder com unknown ou skipped. Uma consulta que excedeu o tempo limite ou uma lista que recusou a consulta nunca conta como pass. 30 pedidos por minuto e 300 por dia por IP entre todas as ferramentas; acima desse limite, a resposta é 429 com Retry-After.

GET/api/v1/tools/spf

O registo SPF de um domínio: a respetiva sintaxe, cada include e redirect seguido e as consultas DNS que toda a árvore contabiliza para o limite de dez. Passe ?domain=example.com.

GET/api/v1/tools/dmarc

O registo DMARC de um domínio, ou do respetivo domínio organizacional quando não tem nenhum: as etiquetas, a política e se cada endereço externo de relatórios aceitou receber relatórios. Passe ?domain=example.com.

GET/api/v1/tools/dkim

A chave DKIM publicada para um seletor: se existe e é descodificada, o respetivo tipo e tamanho e os indicadores de revogação e teste. Passe ?domain=example.com&selector=s1.

GET/api/v1/tools/blocklist

Um endereço IPv4, um endereço IPv6 ou um domínio verificado nas listas de bloqueio DNS utilizadas pelo relatório, com a resposta de cada lista. Passe ?target=203.0.113.5.

GET/api/v1/tools/mx

Os registos MX de um domínio pela ordem em que os remetentes os tentam, com os endereços IPv4 e IPv6 de cada host. São reportados MX nulos, domínios sem MX, hosts que são endereços IP ou CNAMEs e hosts que não são resolvidos, bem como os registos MTA-STS e TLS-RPT. Passe ?domain=example.com.

GET/api/v1/tools/bimi

A configuração BIMI de um domínio em quatro passos: a política DMARC exigida pelo BIMI, o registo em default._bimi, o logótipo SVG verificado em relação ao perfil Tiny PS e o certificado de marca com o respetivo tipo, domínios e data de expiração. Passe ?domain=example.com e &selector= para um seletor diferente de default.

GET/api/v1/tools/ptr

Os registos PTR de um endereço e se algum desses nomes volta a ser resolvido para o mesmo. Uma consulta que tenha falhado dá o estado error; um registo em falta dá o estado fail. Envie ?ip=8.8.8.8.

GET/api/v1/tools/mta-sts

O registo MTA-STS de um domínio e o ficheiro de política para o qual aponta: o modo, os hosts indicados e qualquer host MX que a política omita. Passe ?domain=example.com.

GET/api/v1/tools/tls-rpt

O registo TLS-RPT de um domínio e os endereços que recebem os respetivos relatórios. Passe ?domain=example.com.

GET/api/v1/tools/dnssec

Se a zona de um domínio está assinada, não assinada ou danificada, com base nos respetivos registos DNSKEY e DS. Uma assinatura inválida é distinguida de uma indisponibilidade do resolvedor. Passe ?domain=example.com.

GET/api/v1/tools/dane

Os registos TLSA dos hosts MX, comparados com o certificado apresentado por um host quando foi possível ler esse certificado. Passe ?domain=example.com.

GET/api/v1/tools/smtp

STARTTLS e o certificado nos dois primeiros hosts MX: versão de TLS, emissor, data de expiração e se a cadeia e o nome são válidos. Ligamo-nos apenas a hosts no domínio que você consultou e ignoramos fornecedores de correio, e é partilhado um resultado por endereço durante 6 horas. Não é enviado qualquer correio. Passe ?domain=example.com.

GET/api/v1/tools/ns

Os servidores de nomes de um domínio e se a respetiva zona tem um registo SOA. Um único servidor de nomes é um aviso. Passe ?domain=example.com.

GET/api/v1/tools/registration

Quando expira o registo de um domínio, segundo o RDAP. Restarem menos de 30 dias é um aviso. Uma zona sem serviço RDAP responde com skipped. Passe ?domain=example.com.

POST/api/v1/tools/header

Os cabeçalhos de uma mensagem recebida, enviados como JSON {"headers": "..."} ou como text/plain: o percurso salto a salto com atrasos, TLS e desvio do relógio, os Authentication-Results do próprio recetor, o alinhamento dos domínios From, DKIM d= e Return-Path, e os cabeçalhos DKIM, ARC, de cancelamento da subscrição e de filtros de spam. Tudo o que estiver após a primeira linha vazia é descartado sem ser lido. Os cabeçalhos são processados em memória e não são armazenados, colocados em cache nem registados.

Verifique o domínio todas as noites.
Teste o email antes de ser enviado.

Comum a todos os produtos

Acesso, chaves, formato do relatório, estados, erros, além de OpenAPI e llms.txt para máquinas.

Autenticação

Não existe. Nenhuma chave a pedir, nenhum cabeçalho a definir, nenhuma conta a criar. O slug que recebe é a capacidade: quem o tiver pode ler esse relatório, e mais ninguém o consegue adivinhar.

Isso também significa que deve tratar um slug como uma palavra-passe. Um relatório mostra o assunto, o remetente, o endereço de devolução e a fonte completa da mensagem a qualquer pessoa que tenha a ligação.

Chaves de API pessoais

Everything above works without a key. A key is for automation platforms such as Zapier, where every user's calls come from the platform's servers and per-IP limits would be shared by all of them. With a key, limits count per key (50 tests a day, 3 with placement, 5 permanent mailboxes), the key's tests form a history, and the key can keep permanent mailboxes whose reports only it can read. Send the key as Authorization: Bearer est_live_… on any call on this page. The routes below also take account, a short name of your choosing ([A-Za-z0-9_-], up to 64 characters) that keeps separate lists under one key. GET /api/v1/installations/tests requires it; pass the same one on POST /api/v1/inbox so the test shows up there. The Zapier integration uses zapier.

POST /api/v1/keys

Send JSON {"email":"you@example.com"}. Returns HTTP 201 with key and email. The key is shown once; only its hash is kept. Asking again gives a new key and leaves the earlier ones working. Limit: 5 keys per IP per UTC day. The form on /zapier/ calls this.

GET /api/v1/keys/me

Returns email, key_prefix and created_at of the key in the header, or HTTP 401. Use it to check a key.

GET /api/v1/installations/tests

The key's tests, newest first: ?account=…&limit=50 (up to 100), and before=<slug> for the next page. Each item has slug, created_at, analysis_status (waiting or expired before an email arrived), score_ours, score_compat, placement and changes, the checks that moved since the previous test of the same sending domain. Read the full report at /api/v1/tests/{slug}.

POST /api/v1/installations/mailboxes

Send JSON {"domain":"example.com","account":"…"}. Returns the permanent mailbox of that sending domain: id, address, domain, state, daily_cap and created. HTTP 201 when it is new, 200 when it already existed, 409 when the key keeps as many mailboxes as it may. Subscribe the address to a newsletter or a sequence and every email that arrives is checked. GET on the same path with ?account=… lists them, and DELETE /api/v1/installations/mailboxes/{mailbox_id} stops one.

GET /api/v1/installations/mailboxes/{mailbox_id}/letters

The emails that arrived, oldest first, paged with after_id and next_after_id. settled=true ends the page before the first email still being checked, so paging never skips one. newest=true turns the order round, for a quick look at the latest; settled does nothing with it. Each has test_id, slug, received_at, analysis_status, score_ours, score_compat, subject, from_addr and kind.

GET /api/v1/installations/letters/{slug}

The report of one email in a permanent mailbox, the same JSON as /api/v1/tests/{slug} with report_url null: there is no public page for it. HTTP 410 once the report has expired.

Leitura do relatório

Os campos que contêm a resposta, pela ordem em que provavelmente os pretende consultar.

score_ours0 a 100. O nosso modelo. A autenticação e a infraestrutura têm a maior parte do peso, porque determinam a entrega antes de um filtro ler uma única palavra do conteúdo.
score_compat0 a 10. Reproduz o valor ao estilo do SpamAssassin que as pessoas já utilizam para comparação, para que o relatório seja comparável ao que alguém viu noutro local.
subscoresA mesma escala de 0 a 100 por secção: auth, infra_spam, content, compliance.
checks[]As 42 verificações, cada uma com um estado, uma conclusão numa única linha, os elementos em que a decisão se baseou e o impacto nas duas pontuações.
checks[].citationsA origem da conclusão: a secção da RFC, citada literalmente, e a página onde a Google declara o seu próprio requisito. Selecionadas manualmente em vez de geradas, pelo que são fiáveis.
fixes[]O que alterar, por ordem, com os pontos que vale cada alteração. Os ganhos são calculados voltando a pontuar o relatório, não são estimados.
completeFalse quando não foi possível executar uma verificação. Um item não verificado nunca é uma aprovação, por isso considere a pontuação otimista até ser true.
report_urlA página legível por pessoas. Entregue-a a uma pessoa em vez de uma parede de JSON.

Estados

Uma verificação está num de cinco estados, e a diferença entre dois deles é mais importante do que parece.

passA verificação foi executada e não encontrou qualquer problema.
warnVale a pena corrigir. Custa pontos.
failVai prejudicar a entrega. Custa mais pontos.
ignoradoNão se aplicou. Sem anexos para analisar, sem parte HTML para ponderar. Não é uma aprovação.
erroNão foi possível determinar. Excluído da pontuação e sinalizado, em vez de ser contado como uma aprovação.

analysis_status passa por received, analyzing, checks_ready, failed. ai_status passa por pending, running, ready, fallback, error. O relatório determinístico é final em checks_ready; ai_status apenas acrescenta o plano.

O que pode ser devolvido

202O endereço está reservado e ainda não chegou nenhuma mensagem. O corpo contém o endereço, a data de expiração e o idioma, para que um cliente que não tenha criado a reserva possa ainda assim apresentá-la.
404Esse slug não existe. Nunca existiu ou a reserva foi esquecida.
410O endereço expirou antes de chegar uma mensagem.
409Tentou alterar o idioma depois de a mensagem já ter chegado.
429O limite de testes gratuitos para o seu endereço. Atualmente, este serviço não tem um limite por pessoa; se algum vier a ser definido, o corpo indica quando é reposto.

Quatro coisas que importa saber

Uma mensagem por endereço

A segunda é recusada. O relatório anterior permanece intacto, que é precisamente o objetivo.

Uma hora para o utilizar

O endereço expira; o relatório não. As ligações para os relatórios são permanentes, por isso uma ligação colada num ticket continua a funcionar.

Envie a partir da plataforma

Testar uma campanha a partir de uma conta pessoal avalia essa conta. Quase tudo na secção de autenticação diz respeito à infraestrutura de envio, não ao texto.

Volte a testar após corrigir

Os ganhos esperados são calculados para uma correção de cada vez e não se acumulam. O segundo relatório apresenta o valor real.

Para máquinas

GET/api/health

Disponibilidade. Sem autenticação, sem efeitos secundários.

Experimente primeiro uma manualmente

Demora cerca de um minuto e mostra-lhe exatamente o que o JSON descreve.

Obter um endereço de teste

Sandbox.

Todos os endpoints, com um botão que os executa no serviço em produção. Nada aqui requer uma chave, pelo que um pedido efetuado a partir desta página é real: reserva um endereço real e é contabilizado.

Experimente na sandbox