Watch-IP

مرجع واجهة برمجة فحص البريد الإلكتروني

POST/v1/email/validate

يفحص عنوان بريد إلكتروني واحدًا: الصياغة، والنطاقات المؤقتة المعروفة، وخادم البريد (MX) للنطاق، وأخطاء الكتابة المحتملة، والعناوين الوظيفية، ثم يُرجع حكمًا accept/review/reject مع الأسباب. أرسل جسم JSON بالشكل { "email": "user@example.com" }. صُمّم ليُستدعى من JavaScript الخاص بنموذج التسجيل، باستخدام نموذج المفتاح القابل للنشر المقيَّد بالمصدر نفسه المستخدم في GET /v1/geo. لعدد كبير من العناوين أو لقرار تسجيل من جانب الخادم، استخدم نقاط النهاية المجمّعة ومهام القوائم وفحص التسجيل الموضحة أدناه. جميع الفحوصات على مستوى النطاق والعنوان: لا يتم الاتصال بأي صندوق بريد، لذا لا تُثبت أي نتيجة وجود صندوق البريد أو هوية مالكه أو وصول الرسائل إليه.

المصادقة

تقبل POST /v1/email/validate مفتاحًا قابلًا للنشر مقيَّدًا بالمصدر عبر الترويسة X-Api-Key — نوع المفتاح ونموذج المصادر المسموح بها نفسيهما في GET /v1/geo. أما جميع نقاط النهاية الأخرى في هذه الصفحة (المجمّعة، ومهام القوائم، وفحص التسجيل) فتقبل عناوين عديدة أو عنوان IP عشوائيًا، لذا تتطلب مفتاحك السري عبر Authorization: Bearer ويجب ألا تُستدعى إلا من الخلفية لديك؛ ويحصل المفتاح القابل للنشر فيها على 403.

حقول الاستجابة

email
العنوان الذي أرسلته، مُعادًا تمامًا كما قُدّم.
domain
النطاق بأحرف صغيرة (النطاقات الدولية بترميز punycode)، أو null عندما تكون قيمة syntaxValid هي false.
syntaxValid
ما إذا كان العنوان صحيح الصياغة. ليس فحصًا لوجود صندوق البريد أو لإمكانية التسليم.
isDisposable
ما إذا كان النطاق يطابق مزوّد بريد مؤقت معروفًا — مباشرةً، أو عبر نطاق أب، أو عبر خادم بريد معروف بخدمة نطاقات مؤقتة. تكون دائمًا false عندما تكون syntaxValid هي false.
normalizedEmail
العنوان بعد إزالة المسافات وتحويله إلى أحرف صغيرة مع النطاق بترميز punycode، أو null عندما تكون syntaxValid هي false.
canonicalEmail
قيمة normalizedEmail بعد إزالة أي +tag (وفي Gmail تُزال النقاط ويُحوَّل googlemail.com إلى gmail.com) — احفظها لرصد الشخص نفسه عند تسجيله مرتين. تكون null عندما تكون syntaxValid هي false.
disposableSource
سبب كون isDisposable هي true: list (النطاق نفسه مدرج)، أو parent_domain (نطاق أب مدرج، مثل a.b.mailinator.com)، أو mx_host (خادم بريد النطاق يخدم نطاقات مؤقتة معروفة). تكون null عندما تكون isDisposable هي false.
isFreeProvider
ما إذا كان النطاق مزوّد بريد للمستهلكين مثل gmail.com أو outlook.com. للعلم فقط — لا يغيّر الحكم أبدًا.
isRoleAccount
ما إذا كان الجزء المحلي عنوانًا وظيفيًا مثل admin@ أو info@ أو noreply@.
didYouMean
تصحيح محتمل لخطأ كتابة في العنوان كاملًا (john@gmial.com → john@gmail.com)، أو null. لا يُ«صحَّح» نطاق له خادم بريد عامل خاص به ما لم يكن على بُعد تعديل واحد من مزوّد شائع.
mx.status
found (توجد سجلات MX)، أو implicit (لا يوجد MX لكن يوجد سجل A/AAAA)، أو none (لا هذا ولا ذاك)، أو null_mx (يصرّح النطاق بأنه لا يقبل أي بريد)، أو no_domain (النطاق غير موجود)، أو unknown (فشل الاستعلام أو انتهت مهلته). يكون كائن mx بأكمله null عندما تكون syntaxValid هي false.
mx.host
مضيف MX ذو الأفضلية الأدنى عندما تكون الحالة found، وإلا null. لا يدل على شيء بشأن وجود صندوق البريد الفردي.
verdict
accept أو review أو reject — أشد الشروط الواردة في reasons. توصية لسياستك الخاصة، لا قرار نهائي.
reasons
كل شرط تحقق، من الأشد إلى الأخف؛ فارغة عندما يكون الحكم accept. انظر «الأحكام ورموز الأسباب» أدناه.

الأخطاء

400
جسم طلب غير صالح البنية. الفحص المجمّع: empty_batch أو batch_too_large (أكثر من 100 عنوان). فحص التسجيل: invalid_ip. مهام القوائم: invalid_body أو empty_job أو job_too_large (أكثر من 100,000 عنوان). العنوان غير الصالح لا يُنتج أبدًا 400 — بل نتيجة بحكم reject وسبب invalid_syntax.
401
مفتاح API مفقود أو غير صالح.
403
POST /v1/email/validate: قيمة Origin/Referer في الطلب ليست ضمن قائمة المصادر المسموح بها للمفتاح (لا تُضبط ترويسة CORS، فيحجب المتصفح الاستجابة بغض النظر عن جسم JSON). نقاط النهاية ذات المفتاح السري: استُخدم مفتاح قابل للنشر.
404
job_not_found — لا توجد مهمة قائمة بهذا المعرّف في حسابك.
409
job_not_completed — المهمة ما زالت في قائمة الانتظار أو قيد المعالجة، أو أنها فشلت؛ لا يمكن تنزيل النتائج إلا بعد اكتمالها.
410
job_expired — حُذفت العناوين المرفوعة ونتائج المهمة (بعد 7 أيام من إنشائها).
413
body_too_large — ملف CSV مرفوع لمهمة يتجاوز حجمه 10 ميغابايت.
415
جسم مهمة قائمة ليس JSON ولا text/csv.
429
حد المعدل في الدقيقة، أو monthly_limit_exceeded عندما يتجاوز الطلب الحد الشهري لطلبات الخطة — راجع الأخطاء وحدود المعدل لمعرفة كيفية التمييز بينهما. الدفعة أو مهمة القائمة التي تتجاوز الحد تُرفض كاملةً قبل تنفيذ أي عمل.
503
job_storage_unavailable — تعذّر تخزين مهمة القائمة. لم يُحتسب أي شيء؛ أعد المحاولة.

مثال

الطلب

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"}'

الاستجابة

{
  "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"
  ]
}

الأحكام ورموز الأسباب

يفرض كل شرط حكمًا أدنى؛ ويغلب الأشد، وتسرد reasons جميع الشروط من الأشد إلى الأخف. أما قبول عنوان من مزوّد بريد مجاني فمتروك لتقديرك — لا يغيّر الحكم أبدًا.

invalid_syntax
Reject. العنوان غير صحيح الصياغة (حدود الطول، والأحرف المسموح بها، وموضع النقاط، ونطاق حقيقي لا عنوان IP حرفي). تُرفض أيضًا الأجزاء المحلية المحاطة بعلامات اقتباس — فهي قانونية لكنها لا تُستخدم عمليًا عند التسجيل.
domain_not_found
Reject. النطاق غير موجود في DNS.
no_mail_server
Reject. يصرّح النطاق بأنه لا يقبل أي بريد («null MX»)، أو ليس لديه سجلات MX ولا A/AAAA.
disposable_domain
Reject. النطاق أو نطاق أب له أو خادم بريده يطابق مزوّدي بريد مؤقت معروفين — انظر disposableSource.
typo_suspected
Review. يتضمن didYouMean تصحيحًا محتملًا، مثل gmial.com → gmail.com.
role_account
Review. الجزء المحلي عنوان وظيفي مثل admin@ أو info@ أو support@ أو noreply@، وعادةً ما يكون مشتركًا لا شخصيًا.
implicit_mx
Review. ليس للنطاق سجل MX؛ فيرجع البريد إلى عنوان A/AAAA الخاص به، وهو أمر نادر في نطاقات البريد الحقيقية.
dns_unavailable
Review. فشل استعلام DNS أو انتهت مهلته، لذا إعداد البريد للنطاق غير معروف (mx.status: unknown). ليس دليلًا ضد العنوان.

الفحص المجمّع

POST/v1/email/batch

يفحص من 1 إلى 100 عنوان في طلب واحد بالفحوصات نفسها وشكل النتيجة نفسه في POST /v1/email/validate، نتيجة لكل عنوان بترتيب الإدخال. أرسل { "emails": [...] }. العناوين التي تشترك في النطاق نفسه تتشارك استعلام DNS واحدًا. يُحتسب طلب واحد لكل عنوان ضمن الحد الشهري لخطتك؛ والدفعة التي تتجاوز الحد تُرفض كاملةً مع 429 monthly_limit_exceeded. بالنسبة إلى حد المعدل في الدقيقة، يُحتسب الاستدعاء بأكمله طلبًا واحدًا. بالمفتاح السري فقط.

الطلب

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"]}'

الاستجابة

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

مهام قوائم البريد الإلكتروني

POST/v1/email/jobs

يفحص حتى 100,000 عنوان في الخلفية. أرسل JSON بالشكل { "emails": [...], "filename": "..." } أو جسم text/csv لا يتجاوز 10 ميغابايت: يُستخدم العمود المعنون email (أو e-mail أو email address أو email_address أو mail، دون تمييز لحالة الأحرف)، أو العمود الأول إذا لم يسمِّه أي عنوان؛ ويُكتشف الفاصل تلقائيًا (الفاصلة أو الفاصلة المنقوطة أو علامة الجدولة). تُحتسب المهمة عند إنشائها — طلب واحد لكل عنوان مميّز (تطابق تام)، فتُفحص العناوين المكررة لكنها تُحتسب مرة واحدة — والقائمة التي تتجاوز حدك الشهري تُرفض كاملةً. إذا تعذّرت معالجة جزء من المهمة بعد إعادة المحاولات، تُعلَّم المهمة failed وتُعاد أرصدة الجزء غير المعالَج. يُجيب بـ 202 مع كائن المهمة. بالمفتاح السري فقط؛ ويمكن أيضًا رفع المهام نفسها وتنزيلها من صفحة Email lists في لوحة التحكم.

الطلب

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

الاستجابة

{
  "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"
}

حالة المهمة

GET/v1/email/jobs/{id}

يُرجع كائن المهمة نفسه. استعلم عنه دوريًا حتى تصبح الحالة completed؛ ولا يُحتسب الاستعلام.

status
queued → processing → completed. failed: تعذّرت معالجة جزء من القائمة بعد إعادة المحاولات؛ لا تتوفر نتائج وأُعيدت أرصدة الجزء غير المعالَج. expired: حُذفت العناوين المرفوعة والنتائج بعد 7 أيام من الإنشاء.
total
الصفوف المُرسلة، بما فيها المكررة.
credits
الطلبات المحتسبة: طلب لكل عنوان مميّز.
processed
الصفوف التي فُحصت حتى الآن.
summary
بعد الاكتمال: عدد الصفوف لكل حكم (accept/review/reject) ولكل رمز سبب ظهر. تكون null قبل ذلك.
expiresAt
موعد حذف العناوين المرفوعة والنتائج.

نتائج المهمة

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

يُنزّل ملف CSV يتضمن صفًا لكل صف مُرسل، بترتيب الإرسال — بما في ذلك المكررة. الأعمدة: 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 بفاصلة منقوطة، والخلايا الفارغة تعني null، ويكون mx_status فارغًا للعناوين غير صحيحة الصياغة (لم يُجرَ أي استعلام). العنوان غير الصالح الذي يبدأ بـ = أو + أو - أو @ تُضاف قبله علامة اقتباس مفردة حتى لا تنفّذه تطبيقات الجداول كصيغة. يُرجع 409 إلى أن تكتمل المهمة، و410 بعد انتهاء صلاحيتها. التنزيل لا يُحتسب.

الطلب

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

فحص التسجيل

POST/v1/signup/check

يقيّم تسجيلًا انطلاقًا من عنوان بريده الإلكتروني وعنوان IP في استدعاء واحد، من الخلفية لديك عند إرسال نموذج التسجيل (فالحكم المحسوب في المتصفح يمكن تزويره). أرسل { "email": "...", "ip": "...", "userAgent": "..." } — الحقل userAgent اختياري. تتضمن الاستجابة نتيجة فحص البريد الإلكتروني الكاملة (email)، وبلد عنوان IP وASN الخاص به و— في الخطط التي تشمل بيانات الأمان — مؤشرات VPN/Tor/مركز البيانات/التهديد (ip)، وعمر نطاق البريد بالأيام وفق بيانات التسجيل العامة (RDAP) (emailDomainAgeDays، وتكون null إن كان غير معروف ولمزوّدي البريد الاستهلاكي المعروفين)، ودرجة من 0 إلى 100 (مجموع أوزان الأسباب أدناه، بحد أقصى 100)، وحكمًا: reject عند 60 فأكثر، وreview عند 25 فأكثر، وإلا accept. في خطة بلا بيانات أمان تكون ip.security هي null، وتستخدم الدرجة إشارات البريد فقط، وتتضمن reasons السبب ip_security_unavailable. يُحتسب طلبًا واحدًا. بالمفتاح السري فقط.

invalid_syntax
70
domain_not_found · no_mail_server · disposable_domain
60 لكل منها
ip_tor · ip_threat
40 لكل منهما
ip_vpn
25
new_domain
25 — سُجّل نطاق البريد قبل أقل من 30 يومًا
ip_datacenter
20 — فقط إذا لم يكن عنوان IP مخرج VPN أو Tor أصلًا
automated_user_agent
20 — قيمة userAgent المقدّمة تبدو لروبوت أو برنامج نصي
typo_suspected
15
role_account · implicit_mx
10 لكل منهما
dns_unavailable
5
ip_security_unavailable
0 — للعلم: هذه الخطة لا تتضمن بيانات أمان

الطلب

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"}'

الاستجابة

{
  "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"]
}

الحدود

كل عنوان مفحوص يُحتسب طلبًا واحدًا ضمن الحد الشهري المشترك لخطتك — الفحص الفردي، وكل عنوان في دفعة، وكل عنوان مميّز في مهمة قائمة — وفحص التسجيل طلب واحد. تُقبل الدفعات ومهام القوائم أو تُرفض كاملةً، ولا تُنفّذ جزئيًا أبدًا. يحتسب حد المعدل في الدقيقة استدعاءات HTTP لا العناصر: الدفعة التي تضم حتى 100 عنوان IP أو بريد إلكتروني تُحتسب طلبًا واحدًا، بينما يظل كل عنصر يُحتسب على حدة ضمن الحد الشهري للطلبات. تُحذف ملفات مهام القوائم المرفوعة ونتائجها بعد 7 أيام من إنشاء المهمة. لاستعلامات DNS مهلة زمنية قصيرة: عند فشل أحدها أو انتهاء مهلته تتراجع النتيجة إلى mx.status unknown والسبب dns_unavailable بدلًا من خطأ. بيانات النطاقات المؤقتة مدمجة من ثلاث قوائم مفتوحة المصدر يديرها المجتمع، وتُحدَّث كل بضع ساعات وتُوسَّع بخوادم البريد التي لوحظ أنها تخدم نطاقات مدرجة — انظر مصادر البيانات. قد لا يُرصد مزوّد مؤقت حديث جدًا بعد. جميع الفحوصات على مستوى النطاق والعنوان: لا يتم الاتصال بأي صندوق بريد، لذا لا تُثبت أي نتيجة وجود صندوق البريد أو هوية مالكه أو وصول الرسائل إليه.

صفحات ذات صلة