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;
}
- Kalau body valid tapi masih 500, cek API status page atau hubungi support
- 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:
- API key valid? →
GET /v1/account - Domain verified? →
GET /v1/domains - Akun paused? → Cek
sending_pauseddi response/v1/account - Body JSON valid? →
JSON.parse(body)sebelum kirim - Endpoint URL benar? → Cek plural/singular, versi API (
/v1/) - Rate limit? → Baca header
Retry-After - 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
- [ ] Handle 401 → redirect ke login atau rotate key
- [ ] Handle 429 → retry dengan Retry-After, max 3x
- [ ] Handle 403 → log error, alert ke admin
- [ ] Setup webhook untuk bounce/complaint → auto-remove dari list
- [ ] API key di env variable, bukan di code
- [ ] Test kirim email test sebelum production
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.