Watch-IP

Referensi API Pemeriksaan Email

POST/v1/email/validate

Memeriksa satu alamat email: sintaks, domain sekali pakai/sementara yang dikenal, server email (MX) domain, kemungkinan salah ketik, dan alamat peran, lalu mengembalikan verdict accept/review/reject beserta alasannya. Kirim isi JSON { "email": "user@example.com" }. Dirancang untuk dipanggil dari JavaScript formulir pendaftaran itu sendiri, menggunakan model publishable key yang dikunci origin yang sama dengan GET /v1/geo. Untuk banyak alamat atau keputusan pendaftaran di sisi server, gunakan endpoint batch, list job, dan pemeriksaan pendaftaran yang dijelaskan di bagian bawah halaman ini. Semua pemeriksaan dilakukan di tingkat domain dan alamat: tidak ada mailbox yang dihubungi, sehingga tidak ada hasil yang memastikan bahwa mailbox ada, siapa pemiliknya, atau bahwa email ke alamat tersebut akan sampai.

Autentikasi

POST /v1/email/validate menerima publishable key yang dikunci origin melalui header X-Api-Key — jenis key dan model allowed-origins yang sama dengan GET /v1/geo. Semua endpoint lain di halaman ini (batch, list job, pemeriksaan pendaftaran) menerima banyak alamat atau IP sembarang, sehingga memerlukan secret key Anda melalui Authorization: Bearer dan hanya boleh dipanggil dari backend Anda; publishable key akan mendapat 403 di sana.

Field respons

email
Alamat yang Anda kirim, dikembalikan persis seperti yang dikirimkan.
domain
Domain dalam huruf kecil (domain internasional dalam punycode), atau null jika syntaxValid bernilai false.
syntaxValid
Apakah alamat valid secara sintaks. Bukan pemeriksaan keberadaan mailbox atau keterkiriman.
isDisposable
Apakah domain cocok dengan penyedia email sekali pakai/sementara yang dikenal — secara langsung, melalui domain induk, atau melalui server email yang diketahui melayani domain sekali pakai. Selalu false jika syntaxValid bernilai false.
normalizedEmail
Alamat yang sudah dirapikan dan diubah ke huruf kecil dengan domain dalam punycode, atau null jika syntaxValid bernilai false.
canonicalEmail
normalizedEmail tanpa +tag (dan untuk Gmail, tanpa titik serta googlemail.com dipetakan ke gmail.com) — simpan nilai ini untuk mengenali orang yang sama yang mendaftar dua kali. Null jika syntaxValid bernilai false.
disposableSource
Alasan isDisposable bernilai true: list (domain itu sendiri terdaftar), parent_domain (domain induknya terdaftar, mis. a.b.mailinator.com), atau mx_host (server email domain melayani domain sekali pakai yang dikenal). Null jika isDisposable bernilai false.
isFreeProvider
Apakah domain merupakan penyedia mailbox konsumen seperti gmail.com atau outlook.com. Hanya informasi — tidak pernah mengubah verdict.
isRoleAccount
Apakah bagian lokal merupakan alamat peran seperti admin@, info@, atau noreply@.
didYouMean
Kemungkinan koreksi salah ketik untuk seluruh alamat (john@gmial.com → john@gmail.com), atau null. Domain yang memiliki server email sendiri yang berfungsi tidak akan “dikoreksi” kecuali selisihnya hanya satu suntingan dari penyedia umum.
mx.status
found (record MX ada), implicit (tidak ada MX, tetapi ada record A/AAAA), none (keduanya tidak ada), null_mx (domain menyatakan tidak menerima email), no_domain (domain tidak ada), atau unknown (pencarian gagal atau timeout). Seluruh objek mx bernilai null jika syntaxValid bernilai false.
mx.host
Host MX dengan preferensi terendah jika status bernilai found, selain itu null. Tidak menunjukkan apa pun tentang keberadaan mailbox individual.
verdict
accept, review, atau reject — kondisi paling berat di antara yang ada di reasons. Rekomendasi untuk kebijakan Anda sendiri, bukan keputusan akhir.
reasons
Setiap kondisi yang terpenuhi, dari yang paling berat; kosong jika verdict bernilai accept. Lihat “Verdict dan kode alasan” di bawah.

Error

400
Isi request tidak valid. Batch: empty_batch atau batch_too_large (lebih dari 100 alamat). Pemeriksaan pendaftaran: invalid_ip. List job: invalid_body, empty_job, atau job_too_large (lebih dari 100.000 alamat). Alamat email yang tidak valid tidak pernah menghasilkan 400 — hasilnya adalah verdict reject dengan alasan invalid_syntax.
401
API key hilang atau tidak valid.
403
POST /v1/email/validate: Origin/Referer request tidak ada dalam daftar allowed-origins milik key (tidak ada header CORS yang dipasang, sehingga browser memblokir respons apa pun isi JSON-nya). Endpoint secret key: yang digunakan adalah publishable key.
404
job_not_found — tidak ada list job dengan id ini untuk akun Anda.
409
job_not_completed — job masih dalam antrean atau sedang diproses, atau gagal; hasil hanya dapat diunduh setelah job selesai.
410
job_expired — alamat yang diunggah dan hasil job telah dihapus (7 hari setelah dibuat).
413
body_too_large — unggahan CSV job yang lebih besar dari 10 MB.
415
Isi list job yang bukan JSON maupun text/csv.
429
Rate limit per menit, atau monthly_limit_exceeded jika batas request bulanan paket akan terlampaui — lihat error dan rate limit untuk membedakannya. Batch atau list job yang akan melampaui batas ditolak seluruhnya, sebelum pekerjaan apa pun dilakukan.
503
job_storage_unavailable — list job tidak dapat disimpan. Tidak ada biaya yang dikenakan; coba lagi.

Contoh

Request

curl https://api.watch-ip.com/v1/email/validate \
  -H "X-Api-Key: YOUR_PUBLISHABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "John.Doe+news@Gmial.com"}'

Respons

{
  "email": "John.Doe+news@Gmial.com",
  "domain": "gmial.com",
  "syntaxValid": true,
  "isDisposable": false,
  "normalizedEmail": "john.doe+news@gmial.com",
  "canonicalEmail": "john.doe@gmial.com",
  "disposableSource": null,
  "isFreeProvider": false,
  "isRoleAccount": false,
  "didYouMean": "john.doe+news@gmail.com",
  "mx": {
    "status": "none",
    "host": null
  },
  "verdict": "reject",
  "reasons": [
    "no_mail_server",
    "typo_suspected"
  ]
}

Verdict dan kode alasan

Setiap kondisi menetapkan verdict minimum; yang paling berat menang, dan reasons mencantumkan semuanya, dari yang paling berat. Apakah alamat dari penyedia gratis dapat diterima, Anda yang menentukan — hal itu tidak pernah mengubah verdict.

invalid_syntax
Reject. Alamat tidak valid secara sintaks (batas panjang, karakter yang diizinkan, posisi titik, domain sungguhan dan bukan literal IP). Bagian lokal yang diapit tanda kutip juga ditolak — sah secara aturan, tetapi praktis tidak pernah dipakai saat pendaftaran.
domain_not_found
Reject. Domain tidak ada di DNS.
no_mail_server
Reject. Domain menyatakan tidak menerima email (“null MX”), atau tidak memiliki record MX maupun A/AAAA.
disposable_domain
Reject. Domain, domain induknya, atau server email domain tersebut cocok dengan penyedia email sekali pakai/sementara yang dikenal — lihat disposableSource.
typo_suspected
Review. didYouMean berisi kemungkinan koreksi, seperti gmial.com → gmail.com.
role_account
Review. Bagian lokal adalah alamat peran seperti admin@, info@, support@, atau noreply@, yang biasanya dipakai bersama dan bukan pribadi.
implicit_mx
Review. Domain tidak memiliki record MX; email akan dialihkan ke alamat A/AAAA-nya, yang jarang terjadi pada domain email sungguhan.
dns_unavailable
Review. Pencarian DNS gagal atau timeout, sehingga konfigurasi email domain tidak diketahui (mx.status: unknown). Bukan bukti yang memberatkan alamat tersebut.

Pemeriksaan batch

POST/v1/email/batch

Memeriksa 1–100 alamat dalam satu request dengan pemeriksaan dan bentuk hasil yang sama dengan POST /v1/email/validate, satu hasil per alamat sesuai urutan input. Kirim { "emails": [...] }. Alamat pada domain yang sama berbagi satu pencarian DNS. Dihitung satu request per alamat terhadap batas bulanan paket Anda; batch yang akan melampaui batas ditolak seluruhnya dengan 429 monthly_limit_exceeded. Untuk rate limit per menit, seluruh panggilan dihitung sebagai satu request. Hanya secret key.

Request

curl https://api.watch-ip.com/v1/email/batch \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["user@gmail.com", "someone@mailinator.com"]}'

Respons

{
  "results": [
    { "email": "user@gmail.com", "verdict": "accept", "reasons": [], ... },
    { "email": "someone@mailinator.com", "isDisposable": true, "disposableSource": "list", "verdict": "reject", "reasons": ["disposable_domain"], ... }
  ]
}

List job email

POST/v1/email/jobs

Memeriksa hingga 100.000 alamat di latar belakang. Kirim JSON { "emails": [...], "filename": "..." } atau isi text/csv berukuran maksimal 10 MB: kolom berjudul email (juga e-mail, email address, email_address, atau mail, tanpa membedakan huruf besar-kecil) yang digunakan, atau kolom pertama jika tidak ada judul yang menyebutkannya; pemisah koma, titik koma, dan tab dideteksi otomatis. Biaya job dikenakan saat dibuat — satu request per alamat unik (kecocokan persis), sehingga duplikat tetap diperiksa tetapi dikenakan biaya sekali — dan daftar yang akan melampaui batas bulanan Anda ditolak seluruhnya. Jika sebagian job tidak dapat diproses setelah beberapa kali percobaan ulang, job ditandai failed dan kredit untuk bagian yang tidak diproses dikembalikan. Merespons 202 dengan objek job. Hanya secret key; job yang sama juga dapat diunggah dan diunduh dari halaman Email lists di dasbor.

Request

curl https://api.watch-ip.com/v1/email/jobs \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: text/csv" \
  --data-binary @newsletter.csv

Respons

{
  "id": "5b0d6f5e-8a51-4f7e-9d0e-2c1f3f7f8a11",
  "status": "queued",
  "source": "api",
  "filename": null,
  "total": 12840,
  "credits": 12512,
  "processed": 0,
  "summary": null,
  "createdAt": "2026-09-28T10:00:00.000Z",
  "completedAt": null,
  "expiresAt": "2026-10-05T10:00:00.000Z"
}

Status job

GET/v1/email/jobs/{id}

Mengembalikan objek job yang sama. Lakukan polling hingga status bernilai completed; polling tidak dikenakan biaya.

status
queued → processing → completed. failed: sebagian daftar tidak dapat diproses setelah beberapa kali percobaan ulang; tidak ada hasil yang tersedia dan kredit untuk bagian yang tidak diproses telah dikembalikan. expired: alamat yang diunggah dan hasilnya telah dihapus 7 hari setelah dibuat.
total
Baris yang dikirim, termasuk duplikat.
credits
Request yang dikenakan biaya: satu per alamat unik.
processed
Baris yang sudah diperiksa sejauh ini.
summary
Setelah selesai: jumlah baris per verdict (accept/review/reject) dan per kode alasan yang muncul. Null sebelum itu.
expiresAt
Waktu alamat yang diunggah dan hasilnya dihapus.

Hasil job

GET/v1/email/jobs/{id}/results

Mengunduh CSV dengan satu baris untuk setiap baris yang dikirim, sesuai urutan pengiriman — termasuk duplikat. Kolom: email, normalized_email, verdict, reasons, syntax_valid, is_disposable, disposable_source, is_free_provider, is_role_account, did_you_mean, mx_status, mx_host. reasons dipisahkan titik koma, sel kosong berarti null, dan mx_status kosong untuk alamat yang tidak valid secara sintaks (tidak ada yang dicari). Alamat tidak valid yang diawali =, +, - atau @ diberi awalan apostrof agar aplikasi spreadsheet tidak menjalankannya sebagai rumus. 409 sampai job selesai, 410 setelah kedaluwarsa. Pengunduhan tidak dikenakan biaya.

Request

curl https://api.watch-ip.com/v1/email/jobs/5b0d6f5e-8a51-4f7e-9d0e-2c1f3f7f8a11/results \
  -H "Authorization: Bearer YOUR_SECRET_KEY" -o results.csv

Pemeriksaan pendaftaran

POST/v1/signup/check

Memberi skor pendaftaran dari alamat email dan IP-nya dalam satu panggilan, dari backend Anda saat formulir pendaftaran dikirim (verdict yang dihitung di browser dapat dipalsukan). Kirim { "email": "...", "ip": "...", "userAgent": "..." } — userAgent bersifat opsional. Respons berisi hasil pemeriksaan email lengkap (email), negara dan ASN dari IP serta — pada paket yang menyertakan data keamanan — indikator VPN/Tor/pusat data/ancamannya (ip), usia domain email dalam hari dari data registrasi publik (RDAP) (emailDomainAgeDays, null jika tidak diketahui dan untuk penyedia konsumen terkenal), skor 0–100 (jumlah bobot alasan di bawah, maksimum 100), dan verdict: reject pada 60 atau lebih, review pada 25 atau lebih, selain itu accept. Pada paket tanpa data keamanan, ip.security bernilai null, skor hanya menggunakan sinyal email, dan reasons menyertakan ip_security_unavailable. Dihitung sebagai satu request. Hanya secret key.

invalid_syntax
70
domain_not_found · no_mail_server · disposable_domain
masing-masing 60
ip_tor · ip_threat
masing-masing 40
ip_vpn
25
new_domain
25 — domain email didaftarkan kurang dari 30 hari yang lalu
ip_datacenter
20 — hanya jika IP belum merupakan exit VPN atau Tor
automated_user_agent
20 — userAgent yang diberikan tampak seperti bot atau skrip
typo_suspected
15
role_account · implicit_mx
masing-masing 10
dns_unavailable
5
ip_security_unavailable
0 — informasi: paket ini tidak memiliki data keamanan

Request

curl https://api.watch-ip.com/v1/signup/check \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane@new-startup.io", "ip": "203.0.113.1"}'

Respons

{
  "email": { "email": "jane@new-startup.io", "verdict": "accept", "reasons": [], ... },
  "ip": {
    "ip": "203.0.113.1",
    "country": "US",
    "asn": 64500,
    "asOrganization": "Example Hosting",
    "security": { "isTor": false, "isVpn": false, "isDatacenter": true, "isThreat": false, "isSanctionedNetwork": false }
  },
  "emailDomainAgeDays": 12,
  "score": 45,
  "verdict": "review",
  "reasons": ["new_domain", "ip_datacenter"]
}

Batas

Setiap alamat yang diperiksa dihitung sebagai satu request terhadap batas bulanan bersama paket Anda — pemeriksaan tunggal, setiap alamat dalam batch, setiap alamat unik dalam list job — dan pemeriksaan pendaftaran adalah satu request. Batch dan list job diterima atau ditolak seluruhnya, tidak pernah dipenuhi sebagian. Rate limit per menit menghitung panggilan HTTP, bukan item: satu batch berisi hingga 100 IP atau alamat email dihitung sebagai satu request, sementara setiap item tetap dihitung terpisah terhadap batas request bulanan. Unggahan dan hasil list job dihapus 7 hari setelah job dibuat. Pencarian DNS memiliki anggaran waktu yang singkat: jika salah satunya gagal atau timeout, hasilnya turun menjadi mx.status unknown dan alasan dns_unavailable, bukan error. Data domain sekali pakai digabungkan dari tiga daftar open source yang dikelola komunitas, diperbarui setiap beberapa jam, dan diperluas dengan server email yang teramati melayani domain yang terdaftar — lihat sumber data. Penyedia sekali pakai yang sangat baru mungkin belum ditandai. Semua pemeriksaan dilakukan di tingkat domain dan alamat: tidak ada mailbox yang dihubungi, sehingga tidak ada hasil yang memastikan bahwa mailbox ada, siapa pemiliknya, atau bahwa email ke alamat tersebut akan sampai.

Halaman terkait