Nova Uptime
Guiasapiemail-healthdeveloper

Monitoramento de Email Health pela API Pública da Nova Uptime: Guia de Integração para Desenvolvedores

Construa monitoramento de email health customizado na sua plataforma usando a REST API da Nova Uptime. Guia completo com exemplos de código, rate limits e.

SN
Sumit Nova Uptime
28 de fevereiro de 2026 · 9 min read
Share:

Por que usar a API da Nova Uptime para monitoramento de Email Health?#

Se você gerencia domínios de clientes (plataforma SaaS, provedor de hospedagem, agência), precisa checar programaticamente a saúde do email em todos eles.

Três abordagens:

  1. Manual: Checar cada domínio no dashboard da Nova Uptime. Não escala.
  2. Consultas WHOIS: Escrever parsing customizado de DKIM/SPF/DMARC. Complexo e pouco confiável.
  3. API Pública da Nova Uptime: REST API que cuida de toda a complexidade. Escalável, confiável e mantida.

Este guia cobre a abordagem via API.

Visão geral da API#

Base URL: https://api.novauptime.com/api/v1

Autenticação: Header X-API-Key

Rate Limits: 50 requisições/hora no plano grátis, 1.000/hora nos planos pagos

Formato da resposta:

{
  "success": true,
  "data": { ... },
  "message": "Mensagem opcional"
}

Passo 1: Gere sua API Key#

  1. Faça login em go.novauptime.com
  2. Settings → API Keys
  3. Clique em "Generate New Key"
  4. Copie a chave de 20 caracteres (ex: abc123def456ghi789jk)
  5. Guarde com segurança (não faça commit no git!)

Variável de ambiente:

export NOVAUPTIME_API_KEY="abc123def456ghi789jk"

Passo 2: Cheque o Email Health de um domínio#

Endpoint: GET /domains/{domain}/email-health

Exemplo de requisição:

curl -H "X-API-Key: abc123def456ghi789jk" \
  https://api.novauptime.com/api/v1/domains/example.com/email-health

Resposta:

{
  "success": true,
  "data": {
    "domain": "example.com",
    "score": 92,
    "grade": "A",
    "timestamp": "2026-02-20T10:30:00Z",
    "records": {
      "mx": {
        "status": "configured",
        "value": "mail.example.com"
      },
      "spf": {
        "status": "configured",
        "value": "v=spf1 include:sendgrid.net -all",
        "lookups": 4
      },
      "dkim": {
        "status": "configured",
        "selectors": ["s1", "s2"],
        "configured_count": 2
      },
      "dmarc": {
        "status": "configured",
        "policy": "reject"
      },
      "blacklist": {
        "status": "clean",
        "checked_against": 4,
        "listed_on": 0
      }
    },
    "recommendations": [
      {
        "type": "warning",
        "message": "SPF record has 4 lookups (limit is 10). Consider consolidating includes.",
        "action": "Use SPF flattening service or consolidate email providers"
      }
    ]
  }
}

Casos de uso reais#

Caso 1: Dashboard de agência#

Você é uma agência gerenciando mais de 100 sites de clientes. Quer mostrar a cada cliente o email health dele dentro do seu próprio dashboard.

Implementação:

// Express.js route to fetch email health
app.get("/client/:clientId/email-health", async (req, res) => {
  const clientId = req.params.clientId;

  // Get client's domain from database
  const client = await Client.findById(clientId);
  const domain = client.primaryDomain;

  // Fetch email health from Nova Uptime
  const response = await fetch(
    `https://api.novauptime.com/api/v1/domains/${domain}/email-health`,
    {
      headers: { "X-API-Key": process.env.NOVAUPTIME_API_KEY }
    }
  );

  const emailHealth = await response.json();

  // Return to frontend
  res.json(emailHealth.data);
});

Caso 2: Pontuação automatizada de Email Health#

Avalie todos os domínios de clientes e dispare alertas quando houver degradação.

Implementação:

// Cron job: Check all domains daily
async function dailyEmailHealthAudit() {
  const domains = await Domain.find();

  for (const domain of domains) {
    // Fetch current score
    const current = await fetchEmailHealth(domain.name);

    // Compare to previous day
    const previous = await EmailHealthHistory.findLatest(domain.name);

    if (current.data.score < previous.score - 5) {
      // Score dropped >5 points, alert
      await sendSlackAlert({
        domain: domain.name,
        oldScore: previous.score,
        newScore: current.data.score,
        change: current.data.score - previous.score
      });
    }

    // Store history
    await EmailHealthHistory.create({
      domain: domain.name,
      score: current.data.score,
      timestamp: new Date()
    });
  }
}

Caso 3: Auditoria em massa de domínios#

Você adquiriu um concorrente. São 50 novos domínios de clientes. Você quer o status de email health de todos.

Implementação:

// Fetch email health for 50 domains
async function auditAcquiredDomains(acquiredDomains) {
  const results = [];

  // Fetch with concurrency limit (5 at a time)
  for (const domain of acquiredDomains) {
    const health = await fetchEmailHealth(domain);
    results.push({
      domain,
      score: health.data.score,
      grade: health.data.grade,
      issues: health.data.recommendations
    });
  }

  // Export to CSV
  const csv = convertToCSV(results);
  fs.writeFileSync("email-health-audit.csv", csv);

  // Summary: 40 domains healthy, 10 need fixes
  console.log(`Healthy: ${results.filter(r => r.score > 80).length}`);
  console.log(`Need fixes: ${results.filter(r => r.score < 80).length}`);
}

Padrões de API para produção#

Padrão 1: Cache com expiração#

Não chame a API a cada requisição. Faça cache dos resultados localmente.

const redis = require("redis");
const client = redis.createClient();

async function getEmailHealthCached(domain, maxAge = 3600) {
  // Try cache first
  const cached = await client.get(`email-health:${domain}`);
  if (cached) {
    return JSON.parse(cached);
  }

  // Cache miss, fetch from API
  const health = await fetchEmailHealth(domain);

  // Store in cache for 1 hour
  await client.setex(
    `email-health:${domain}`,
    maxAge,
    JSON.stringify(health.data)
  );

  return health.data;
}

Padrão 2: Tratamento de rate limit#

A API da Nova Uptime tem rate limits. Lide com eles de forma elegante.

async function fetchWithRetry(domain, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(
        `https://api.novauptime.com/api/v1/domains/${domain}/email-health`,
        {
          headers: { "X-API-Key": process.env.NOVAUPTIME_API_KEY },
          timeout: 10000
        }
      );

      if (response.status === 429) {
        // Rate limited, wait before retry
        const retryAfter = response.headers.get("Retry-After") || (2 ** i);
        console.log(`Rate limited. Retrying in ${retryAfter}s`);
        await new Promise(r => setTimeout(r, retryAfter * 1000));
        continue;
      }

      if (!response.ok) throw new Error(`HTTP ${response.status}`);

      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      console.log(`Attempt ${i + 1} failed, retrying...`);
      await new Promise(r => setTimeout(r, (2 ** i) * 1000));
    }
  }
}

Padrão 3: Processamento em lote#

Quando estiver checando mais de 100 domínios, faça as requisições em lote de forma eficiente.

async function batchEmailHealthCheck(domains) {
  const batchSize = 10; // 10 concurrent requests
  const results = [];

  for (let i = 0; i < domains.length; i += batchSize) {
    const batch = domains.slice(i, i + batchSize);

    // Process batch concurrently
    const batchResults = await Promise.all(
      batch.map(domain => fetchEmailHealth(domain))
    );

    results.push(...batchResults);

    // Log progress
    console.log(`Processed ${Math.min(i + batchSize, domains.length)}/${domains.length}`);
  }

  return results;
}

Padrão 4: Armazenando resultados localmente#

Guarde os resultados de email health no seu próprio banco de dados para acompanhamento histórico.

// Database model
const EmailHealthSchema = {
  domain: String,
  score: Number,
  grade: String,
  records: {
    mx: Object,
    spf: Object,
    dkim: Object,
    dmarc: Object,
    blacklist: Object
  },
  timestamp: Date,
  createdAt: Date
};

async function storeEmailHealth(domain) {
  const health = await fetchEmailHealth(domain);

  // Store in DB
  const record = new EmailHealthLog({
    domain,
    score: health.data.score,
    grade: health.data.grade,
    records: health.data.records,
    timestamp: new Date(health.data.timestamp),
    createdAt: new Date()
  });

  await record.save();

  return record;
}

Padrão 5: Alertas em mudanças#

Acompanhe mudanças e avise o time quando algo quebrar.

async function monitorEmailHealth(domain) {
  const current = await getEmailHealthCached(domain);
  const previous = await EmailHealthLog.findLatest(domain);

  if (!previous) {
    // First check, just store it
    await storeEmailHealth(domain);
    return;
  }

  // Detect changes
  const scoreChange = current.score - previous.score;

  if (scoreChange < -10) {
    // Major degradation
    await alertSlack({
      channel: "#email-alerts",
      message: `
        ${domain}: Email health degraded
        Previous: ${previous.score} (${previous.grade})
        Current: ${current.score} (${current.grade})
        Change: ${scoreChange < 0 ? "" : "+"}${scoreChange}

        Issues: ${current.recommendations.map(r => r.message).join("\n")}
      `
    });
  }
}

Tratamento de erros#

Cenários de erro comuns:

async function robustEmailHealthCheck(domain) {
  try {
    const health = await fetchWithRetry(domain);
    return health.data;
  } catch (error) {
    if (error.code === "ENOTFOUND") {
      // Domain doesn't exist
      console.error(`Domain ${domain} not found`);
      return null;
    } else if (error.statusCode === 401) {
      // Invalid API key
      console.error("Invalid Nova Uptime API key");
      return null;
    } else if (error.statusCode === 429) {
      // Rate limited (even after retries)
      console.error("Rate limit exceeded");
      return null;
    } else {
      // Unknown error
      console.error(`Error checking ${domain}: ${error.message}`);
      return null;
    }
  }
}

Integração no frontend#

Exemplo de componente React#

import { useState, useEffect } from 'react';

function EmailHealthCard({ domain }) {
  const [health, setHealth] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchHealth() {
      try {
        const response = await fetch(`/api/email-health/${domain}`);
        const data = await response.json();
        setHealth(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    }

    fetchHealth();
  }, [domain]);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div className="email-health-card">
      <h3>{domain}</h3>
      <div className={`score score-${health.grade}`}>
        {health.score}/100 ({health.grade})
      </div>

      <div className="records">
        {Object.entries(health.records).map(([key, value]) => (
          <div key={key} className={`record ${value.status}`}>
            <strong>{key.toUpperCase()}</strong>: {value.status}
          </div>
        ))}
      </div>

      {health.recommendations.length > 0 && (
        <div className="recommendations">
          <h4>Recommendations:</h4>
          <ul>
            {health.recommendations.map((rec, i) => (
              <li key={i} className={rec.type}>
                {rec.message}
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

Referência de documentação da API#

Base URL: https://api.novauptime.com/api/v1

Endpoints:

GET /domains/{domain}/email-health
  → Check email health for domain
  → Rate limit: 50/hour (free), 1000/hour (paid)
  → Response: Email health score, grade, records, recommendations

GET /domains/{domain}/incidents
  → Get last 20 downtime incidents
  → Optional param: limit, offset

GET /domains/{domain}/history
  → Get check history (configurable hours, max 720h)
  → Optional params: hours (default 168), limit (default 500)

GET /domains
  → List user's domains (paginated, max 50/page)
  → Optional params: page, limit

Boas práticas#

  1. Faça cache agressivo: Email health não muda com frequência. Faça cache de 1 a 24 horas.
  2. Junte requisições em lote: Cheque 10 domínios em paralelo, não 1 de cada vez.
  3. Trate erros com elegância: Problemas de rede acontecem. Faça retry com backoff exponencial.
  4. Monitore a API: Acompanhe seu uso da API. Se estiver perto do rate limit, aumente o cache.
  5. Proteja sua API key: Nunca faça commit no git. Use variáveis de ambiente.
  6. Teste rate limits: Simule alto volume antes de subir para produção.

Resumo: checklist de integração da API#

  • ✅ Gerar e proteger a API key
  • ✅ Implementar a checagem básica de email health
  • ✅ Adicionar camada de cache (Redis ou em memória)
  • ✅ Implementar tratamento de rate limit
  • ✅ Adicionar tratamento de erro para falhas comuns
  • ✅ Testar com seu domínio real
  • ✅ Construir componente frontend para exibir resultados
  • ✅ Configurar alertas para mudanças no score
  • ✅ Documentar a gestão da API key na wiki do time
  • ✅ Monitorar uso e cota da API

Comece hoje#

A API pública da Nova Uptime está disponível no plano grátis. Gere sua primeira API key em Settings e comece a integrar checagens de email health na sua plataforma.

Para a referência detalhada da API, acesse a documentação da API da Nova Uptime.

Monitor Your Website Before It Goes Down

Get uptime monitoring, SSL tracking, domain expiry alerts, and email health checks. Free plan — no credit card required.

Start Monitoring Free

Artigos relacionados