← Back to all posts
2026-09-17 · MailAnvil Team

Debug Email API: Cara Membaca dan Menangani Error Response dari Email API

Setelah integrasi email API, error pasti datang. Response 401 tanpa penjelasan. Request yang diam-diam gagal. Email yang seharusnya terkirim tapi nyangkut di "queued". Developer yang paham baca error response bisa fix dalam 5 menit. Yang tidak paham? Buang waktu berjam-jam di log yang tidak jelas.

Berikut panduan membaca error response dari email API — khususnya MailAnvil, tapi prinsipnya berlaku universal di email API modern.

Struktur Error Response yang Benar

Email API yang well-designed punya error response konsisten. Di MailAnvil, semua error punya bentuk yang sama:

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key"
  }
}

Dua field penting: - code — kode machine-readable. Inilah yang harus kamu handle di kode. Jangan parse message untuk branching logic. - message — deskripsi human-readable. Untuk debugging di terminal atau log.

Kalau email API yang kamu pakai tidak punya code field dan hanya mengembalikan message saja, itu red flag — kamu tidak bisa handle error secara programmatic.

Daftar Error Code dan Cara Mengatasinya

401 Unauthorized — API Key Salah atau Tidak Ada

{ "error": { "code": "unauthorized", "message": "Invalid or missing API key" } }

Penyebab umum: - API key tidak dikirim di header Authorization - API key sudah di-revoke dari dashboard - Copy-paste key ada spasi atau karakter tersembunyi

Fix:

# Test manual — ganti dengan API key kamu
curl -H "Authorization: Bearer key_xxxxxxxx" https://api.mailanvil.com/v1/account

Kalau response 401, key-nya invalid. Buat baru dari dashboard. Di MailAnvil, key disimpan sebagai SHA-256 hash — tidak bisa "diperbaiki", harus generate ulang.

403 Forbidden — Domain atau Akun Terblokir

{ "error": { "code": "forbidden", "message": "Domain not verified" } }

Penyebab umum: - Domain belum diverifikasi DKIM di MailAnvil - Akun sending_paused karena bounce/complain rate tinggi - Customer tidak punya akses ke resource yang diminta

Fix: 1. Cek status domain dari GET /v1/domains — pastikan dkim_status: "verified" 2. Cek akun dari GET /v1/account — pastikan sending_paused: false 3. Kalau domain "pending", cek DNS record DKIM di panel DNS provider kamu

Di MailAnvil, INV-1 enforced: email tidak akan dikirim kalau domain belum verified. Tidak ada bypass.

429 Too Many Requests — Rate Limit

{ "error": { "code": "rate_limited", "message": "Rate limit exceeded. Retry after 1s" } }

Header Retry-After: 1 memberitahu berapa detik menunggu sebelum retry.

Penyebab umum: - Loop tanpa delay mengirim ratusan email sekaligus - Test script yang terlalu agresif - Banyak worker/service yang pakai API key yang sama

Fix:

// ✅ Pattern yang benar
async function sendWithRetry(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (err) {
      if (err.status === 429) {
        const retryAfter = parseInt(err.headers['retry-after'] || '1');
        await new Promise(r => setTimeout(r, retryAfter * 1000));
        continue;
      }
      throw err; // Error lain, langsung throw
    }
  }
  throw new Error('Max retries exceeded');
}

Jangan: langsung retry tanpa baca Retry-After. Jangan retry lebih dari 3x — kalau masih 429, ada masalah di konfigurasi, bukan di retry logic.

404 Not Found — Resource Tidak Ada

{ "error": { "code": "not_found", "message": "Email not found" } }

Penyebab umum: - Email ID salah atau typo - Email sudah diarsipkan (>90 hari, pindah ke R2) - Endpoint URL salah (misal /v1/email/ bukan /v1/emails/)

Fix: - Cek ulang URL endpoint — plural atau singular? - Cek GET /v1/emails?limit=5 untuk list email terakhir, pastikan ID-nya benar - Kalau email lama (>90 hari), sudah diarsipkan. Logs hanya tersimpan 90 hari di D1.

500 Internal Server Error — Masalah di Server

{ "error": { "code": "internal_error", "message": "An unexpected error occurred" } }

Penyebab umum: - Body request malformed (JSON invalid, field wajib missing) - Server-side bug di email API

Fix: 1. Validasi JSON sebelum kirim:

// Cek syntax JSON sebelum POST
try {
  JSON.parse(body);
} catch (e) {
  console.error('Invalid JSON:', e.message);
  return;
}
  1. Kalau body valid tapi masih 500, cek API status page atau hubungi support
  2. Di MailAnvil, 500 jarang terjadi — kecuali body request tidak sesuai Zod schema

Error Response yang TIDAK Boleh Diabaikan

Bounce dan Complaint — Bukan Error di Request, tapi Konsekuensi

Email yang berhasil dikirim (202) belum tentu berhasil sampai di inbox. Bounce dan complaint datang lewat webhook atau callback, bukan di response POST.

// Webhook payload untuk bounce
{
  "event": "bounce",
  "email_id": "em_xxxxxx",
  "recipient": "[email protected]",
  "type": "hard",
  "diagnostic": "550 5.1.1 The email account does not exist"
}

Tindakan: - Hard bounce → hapus dari mailing list, jangan retry - Soft bounce → retry 1-2x, kalau masih gagal, treat sebagai hard bounce - Complaint → hapus dari list SEGERA, tambahkan ke suppression list

Di MailAnvil, INV-5 enforced: kalau complaint rate >0.3% atau hard bounce >5% (min 100 sends), akun otomatis di-pause. Manual unpause only.

Sending Paused — Akun Terkunci

{ "error": { "code": "sending_paused", "message": "Account sending is paused" } }

Ini bukan error di request. Ini konsekuensi dari reputation yang buruk. Email API mempause akun untuk melindungi infrastruktur.

Fix: - Hubungi support email API untuk unpause - Bersihkan suppression list - Audit recipient list — hapus email invalid

Debugging Checklist untuk Developer

Setiap kali error muncul, cek urutan ini:

  1. API key valid?GET /v1/account
  2. Domain verified?GET /v1/domains
  3. Akun paused? → Cek sending_paused di response /v1/account
  4. Body JSON valid?JSON.parse(body) sebelum kirim
  5. Endpoint URL benar? → Cek plural/singular, versi API (/v1/)
  6. Rate limit? → Baca header Retry-After
  7. Recipient suppressed? → Cek suppression list

Contoh Debugging di Terminal

# 1. Cek akun
curl -s -H "Authorization: Bearer $MAILANVIL_API_KEY" \
  https://api.mailanvil.com/v1/account | jq .

# 2. Cek domains
curl -s -H "Authorization: Bearer $MAILANVIL_API_KEY" \
  https://api.mailanvil.com/v1/domains | jq .

# 3. Kirim test email
curl -s -X POST -H "Authorization: Bearer $MAILANVIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"[email protected]","to":["[email protected]"],"subject":"Test","text":"Hello"}' \
  https://api.mailanvil.com/v1/send | jq .

# 4. Cek email terakhir
curl -s -H "Authorization: Bearer $MAILANVIL_API_KEY" \
  "https://api.mailanvil.com/v1/emails?limit=5" | jq .

Gunakan jq untuk format response. Kalau tidak punya jq, ganti dengan python3 -m json.tool.

Kesalahan Fatal yang Sering Terjadi

Kesalahan Mengapa Fatal Fix
Retry tanpa baca Retry-After Bisa double-send Parse header dulu
Parse error message untuk branching API bisa ubah message kapan saja Pakai error code
Ignore 401 Auth silent failure, semua request gagal Handle di middleware
Tidak cek bounce via webhook Reputation turun, akun di-pause Setup webhook endpoint
Simpan API key di code Key leak ke git, langsung compromise Pakai env variable

Checklist Sebelum Deploy

CTA

MailAnvil memberikan error response yang konsisten dan jelas — setiap error punya code dan message. Tidak perlu menebak-nebak.

Coba MailAnvil gratis di mailanvil.com — daftar dalam 30 detik, langsung dapat API key, 500 email gratis/bulan.

Untuk developer Indonesia: pricing dalam Rupiah, support Bahasa Indonesia, bayar pakai QRIS atau GoPay.