Email Spam Tester

API فحص البريد العشوائي
للرسائل وصندوق الوارد والنطاق

أرسل إلينا رسالة حقيقية واحدة، أو زودنا بنطاق فقط. تأتي جميع الاستجابات بصيغة JSON.

لا مفتاح، لا حساب.

الطلب

# reserve a single-use address

$ curl -sX POST '.../api/v1/inbox?lang=en'

# send your message to that address, then

$ curl -s '.../api/v1/tests/k7m2x9qplw4tz8vn3b6c/status'

# read the report

$ curl -s '.../api/v1/tests/k7m2x9qplw4tz8vn3b6c'

الاستجابة

200 OK

{
  "address": "test-k7m2x9qplw4tz8vn3b6c@t.email-spam-tester.com",
  "slug": "k7m2x9qplw4tz8vn3b6c",
  "expires_at": "2026-10-31T13:00:00Z"
}

200 OK

{
  "analysis_status": "checks_ready",
  "ai_status": "running",
  "checks_done": 42,
  "checks_total": 42
}

200 OK

{
  "score_ours": 86.4,
  "score_compat": 9.2,
  "subscores": {"auth": 100.0, "infra_spam": 78.1, "content": 92.0},
  "complete": true,
  "checks": [{"id": "auth.dmarc", "status": "warn"}],
  "fixes": [{"id": "dmarc-enforce", "gain_ours": 4.0}]
}

الطلب

# create a test

$ curl -sX POST '.../api/v1/placement' \ -d '{"public_results_accepted":true}'

# put the marker in the subject, send once to all, then

$ curl -s '.../api/v1/placement/wR3kP9xLq2vT8mZc'

الاستجابة

201 Created

{
  "marker": "est-3f9a1c7e2b4d6a80c5e1f2d3",
  "status": "waiting",
  "results": [{"provider": "gmail", "placement": "pending"}],
  "fleet": {"status": "observing", "results": [
    {"provider": "yahoo", "placement": "pending"},
    {"provider": "outlook", "placement": "pending"}
  ]}
}

200 OK

{
  "status": "complete",
  "results": [{"provider": "gmail", "placement": "primary"}],
  "fleet": {"status": "finished", "results": [
    {"provider": "yahoo", "placement": "inbox"},
    {"provider": "outlook", "placement": "spam"}
  ]}
}

الطلب

# no email needed, one GET

$ curl -s '.../api/v1/infra/check?domain=example.com'

# compare with your last run

$ curl -s '.../api/v1/infra/check?domain=example.com&diff=true' \ | jq '.diff'

الاستجابة

200 OK

{
  "domain": "example.com",
  "ok": false,
  "status": "fail",
  "score": 78,
  "coverage": {"answered": 7, "total": 8},
  "sections": {"ptr": {"status": "fail", "core": true}}
}

200 OK

{
  "changed": true,
  "worsened": true,
  "status_from": "pass",
  "score_from": 100,
  "changes": [{"path": "dkim.key.mail.sha256", "kind": "removed",
               "severity": "critical", "effect": "worsened"}]
}
في هذه الصفحة

اختبار البريد الإلكتروني

نقرأ رسالة حقيقية واحدة من البداية إلى النهاية: المحتوى والتوقيع والرؤوس والخادم الذي أرسلها. تحصل على نتيجة وقائمة بالإصلاحات وكل فحص تستند إليه.

بدء سريع

ثلاثة استدعاءات. بلا مفتاح، بلا حساب، بلا تسجيل. طلبان ورسالة بريد إلكتروني واحدة. الاستدعاء الثالث موجود فقط لأن التحليل يستغرق بضع ثوانٍ.

  1. احجز عنوانًا

    أرسل طلب POST إلى نقطة نهاية صندوق الوارد. ستحصل على عنوان يقبل رسالة واحدة فقط وتنتهي صلاحيته خلال ساعة، بالإضافة إلى المعرّف المختصر الذي يُستخدم مفتاحًا لكل ما عدا ذلك.

    الطلب

    # 1. reserve a single-use address
    curl -sX POST 'https://email-spam-tester.com/api/v1/inbox?lang=en'

    الاستجابة

    {
      "address": "test-<slug>@t.email-spam-tester.com",
      "slug": "<slug>",
      "expires_at": "2026-01-01T12:00:00Z"
    }
  2. أرسل إليه الرسالة الفعلية

    عبر SMTP، ومن المنصة التي سترسل الحملة. نصف الفحوصات يقرأ الترويسات التي تضيفها منصة الإرسال، لذا فإن رسالة مُنشأة يدويًا تقيس الشيء الخطأ.

    الطلب

    # 2. send your message to that address, from your own platform
    To: test-<slug>@t.email-spam-tester.com
  3. استقصِ الحالة، ثم اقرأ التقرير

    حجم نقطة نهاية الحالة بضع مئات من البايتات، وهي تخبرك بما إذا كان التقرير الكامل يستحق الجلب بعد. أما التقرير نفسه فيمتد إلى عدة آلاف من الأسطر.

    الطلب

    # 3. poll
    curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>/status'

    الاستجابة

    {
      "slug": "<slug>",
      "analysis_status": "checks_ready",
      "ai_status": "running",
      "checks_done": 42,
      "checks_total": 42
    }

    الطلب

    # 4. read the report once analysis_status is checks_ready
    curl -s 'https://email-spam-tester.com/api/v1/tests/<slug>'

    الاستجابة

    {
      "report_url": "https://email-spam-tester.com/t/<slug>",
      "score_ours": 86.4,
      "score_compat": 9.2,
      "subscores": {"auth": 100.0, "infra_spam": 78.1, "content": 92.0, "compliance": 75.0},
      "complete": true,
      "checks": [
        {
          "id": "auth.dmarc",
          "status": "warn",
          "title": "DMARC result",
          "summary": "DMARC passes, but the policy is p=none.",
          "weight_ours": -4.0,
          "evidence": {"policy": "none", "aligned": "dkim"},
          "citations": {"standards": [{"title": "RFC 9989 §4.7", "quote": "..."}]}
        }
      ],
      "fixes": [
        {"id": "dmarc-enforce", "gain_ours": 4.0, "gain_compat": 0.0,
         "fix": {"title": "Move DMARC to quarantine", "severity": "medium"}}
      ]
    }

احجز عنوانًا، وأرسل الرسالة التي كنت على وشك إرسالها إلى قائمتك، ثم اقرأ التقرير. كل ما تعرضه الصفحة موجود في JSON، بما في ذلك النتيجة، وجميع الفحوصات الـ42 مع أدلتها، وقسم المعيار الذي تستند إليه كل نتيجة.

أول 100,000 تقرير مجاني، من دون مفتاح ومن دون حساب. إذا كنت تربط وكيلاً بدلاً من برنامج نصي، فإن خادم MCP أنسب من الاستقصاء الدوري.

نقاط النهاية

العنوان الأساسي https://email-spam-tester.com. كل شيء يستجيب بصيغة JSON.

POST/api/v1/inbox

يحجز عنوانًا للاستخدام مرة واحدة. كلا المعلمتين اختياريتان.

langاللغة التي ستُكتب بها خطة الإصلاح ونتائج كل فحص، على هيئة رمز ISO. تُحدَّد الآن لأن الرسالة تصل عبر SMTP بعد دقائق ولا تحمل أي إشارة إلى هوية من ينتظرها. عند إدخال رمز غير معروف، يُستخدم الإنجليزية بدلًا منه.
utm_source, utm_medium, utm_campaignتُمرَّر إلى تحليلاتنا. مفيدة إذا كنت تقيس تكاملك الخاص.

GET/api/v1/tests/{slug}/status

قليلة التكلفة عند الاستطلاع. تُرجع حقلي الحالة ومدى تقدم الفحوصات، ولا شيء غير ذلك.

استطلع هذه بدلًا من التقرير. تصل analysis_status أولًا إلى checks_ready، ثم تصل خطة AI ضمن ai_status بعد نحو دقيقة، لذلك لا يضطر المستدعي الذي يريد الفحوصات الحتمية فقط إلى انتظار الخطة.

GET/api/v1/tests/{slug}

التقرير كاملًا. يستجيب بالحالة 202 ما دام العنوان محجوزًا ولم تصل أي رسالة بعد، وبالحالة 200 بعد وصولها.

GET/api/v1/tests/{slug}/message

الرسالة كما تم تسليمها تمامًا: كل ترويسة بترتيب النقل، وكلا المتنين، وقائمة المرفقات، والمصدر الخام. تُجلب بشكل منفصل لأن التقرير يُستطلع وقد يصل حجم هذه البيانات إلى ميغابايت واحد.

تُحذف الرسالة الأولية وفق جدولها الزمني الخاص، قبل التقرير. بعد ذلك تستجيب نقطة النهاية هذه بالسبب بدلاً من المصدر.

PUT/api/v1/tests/{slug}/locale

يغيّر لغة حجز لم يُستخدم بعد. لوكيل يعرف اللغة التي يقرأ بها مستخدمه بعد أن يكون قد طلب العنوان بالفعل. يُرفض الطلب بعد وصول الرسالة، لأن التحليل يكون قيد التشغيل حينها.

موضع صندوق الواردتجريبي

أرسل رسالة واحدة إلى قائمة من صناديق بريد الاختبار واعرف أين وصلت لدى Gmail وOutlook وYahoo ومزودي الخدمة الآخرين: صندوق الوارد أو العروض الترويجية أو الرسائل المزعجة.

بدء سريع

  1. أنشئ اختبارًا

    أرسل طلب POST إلى نقطة نهاية الموضع. ستحصل على علامة وصناديق بريد الاختبار.

    الطلب

    # 1. create a test
    curl -sX POST 'https://email-spam-tester.com/api/v1/placement' \
      -H 'Content-Type: application/json' \
      -d '{"public_results_accepted":true}'

    الاستجابة

    {
      "slug": "<slug>",
      "marker": "est-3f9a1c7e2b4d6a80c5e1f2d3",
      "status": "waiting",
      "deadline": "2026-10-31T12:30:00Z",
      "poll_after_seconds": 60,
      "results": [
        {"address": "<seed>", "provider": "gmail", "kind": "Gmail",
         "placement": "pending", "observed_at": null}
      ],
      "fleet": {
        "status": "observing",
        "results": [
          {"address": "<mailbox>", "provider": "yahoo", "available": true,
           "placement": "pending", "coverage": "pending"}
        ]
      }
    }
  2. أرسل رسالة واحدة إلى كل صندوق بريد

    ضع العلامة في الموضوع وأرسل من منصتك المعتادة إلى جميع العناوين دفعة واحدة.

    الطلب

    # 2. one message to every address, with the marker in the subject
    Subject: October invoice est-3f9a1c7e2b4d6a80c5e1f2d3
    To: <seed>, <mailbox>, ...
  3. استعلم عن المجلدات

    يُملأ كل عنوان بمزوّده ومجلده. واصل الاستعلام حتى تتوقف الحالة عن كونها waiting.

    الطلب

    # 3. poll for the folders
    curl -s 'https://email-spam-tester.com/api/v1/placement/<slug>'

    الاستجابة

    {
      "status": "complete",
      "received": 2,
      "total": 2,
      "results": [
        {"address": "<seed>", "provider": "gmail", "kind": "Gmail",
         "placement": "primary", "observed_at": "2026-10-31T12:04:11Z"},
        {"address": "<seed>", "provider": "gmail", "kind": "Google Workspace",
         "placement": "promotions", "observed_at": "2026-10-31T12:04:11Z"}
      ],
      "fleet": {
        "status": "finished",
        "results": [
          {"address": "<mailbox>", "provider": "yahoo", "available": true,
           "placement": "inbox", "coverage": "ok"},
          {"address": "<mailbox>", "provider": "outlook", "available": true,
           "placement": "spam", "coverage": "ok"}
        ]
      }
    }

نقاط النهاية

An optional test using public GMass seed inboxes and available project test mailboxes, alone or alongside the email score. Explain to the sender that GMass receives their email and publishes its subject, sender name and placement before creating a test. Use all test mailboxes for non-confidential test messages only.

GET /api/v1/placement/availability

Returns providers: the provider identifiers of currently healthy, admitted project mailboxes. No addresses or credentials are exposed. This read does not create a test or contact GMass. Actual recipients are allocated at creation and may differ as availability or capacity changes.

POST /api/v1/placement

Send JSON {"public_results_accepted":true}. Returns HTTP 201 with slug, marker, results (the seed addresses), deadline and expires_at. Limit: 20 tests per IP per UTC day.

For one-send combined testing, first reserve an email score address and include its score_slug in the placement creation JSON. Repeated creation for that score returns the same placement test. Send the marked email to the score address, every returned seed and every available fleet.results address; keep the main /t/<score_slug> report link. Creating a link after the score address was used or expired returns HTTP 409.

GET /api/v1/placement/by-score/{score_slug}

Read and refresh the placement run attached to the main email test. The response has the same format and polling limits as the standalone endpoint below. HTTP 404 means placement was not included or its stored results have been removed.

GET /api/v1/placement/{slug}

Use poll_after_seconds (normally 60 seconds) while the page is open. Upstream errors trigger a shared cooldown. Add the marker to the subject and send through the sender's normal platform to every seed. Observations are saved for 30 days. Collection ends after 30 minutes or when all seeds have results.

status: waiting, complete or timed_out. Each result has an address, provider, kind, placement and observed_at. Placement is primary, promotions, inbox, updates, social, forums, spam, unknown, pending or not_observed. Missing results do not mean Spam; Promotions is an inbox category. provider_error indicates an upstream outage without discarding saved observations. HTTP 404 means unknown, 410 expired, 429 quota exhausted, and 503 no test inboxes available at creation.

The optional fleet object contains independently collected project mailbox results, with status observing, settling or finished. Refresh every 30 seconds until it finishes, even when Gmail has completed. Each fleet result includes address, provider, available, placement, category and coverage. Exclude unavailable addresses from new sends; retain their saved observations. Category data may be unavailable even when the physical folder is known.

If GMass is unavailable at creation but project mailboxes can be allocated, provider is fleet and the top-level seed results are empty. Use fleet.results; do not interpret an empty Gmail list as successful delivery. Existing runs never gain new recipient addresses silently.

فحص البنية التحتية

يفحص طلب GET واحد إعداد البريد لنطاق ما من دون إرسال أي شيء، ويحتفظ بالنتيجة، ويخبرك بما تغير منذ آخر تشغيل. لا يلزم مفتاح. في cron، ينتهي السطر أدناه برمز غير صفري عندما يكون النطاق معطّلًا أو عندما يتغير إعداده بطريقة مؤثرة.

بدء سريع

  1. نفّذ طلب GET واحدًا

    مرّر النطاق. تضيف ip عناوين الإرسال الخاصة بك، وتحدد selector محددات DKIM المراد قراءتها.

    الطلب

    curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true'
  2. اقرأ النتيجة

    تمثل ok الإجابة لنص برمجي، وتوضح sections أي جزء فشل.

    الاستجابة

    {
      "id": "ir_01JB8Y4T2M6K9QZ7H3V5N1XWDA",
      "domain": "example.com",
      "checked_at": "2026-10-31T12:00:00Z",
      "ok": false,
      "status": "fail",
      "score": 78,
      "coverage": {"answered": 7, "total": 8},
      "ips": [{"ip": "203.0.113.5", "sources": ["mx", "spf"], "managed": false}],
      "sections": {
        "dkim": {"status": "pass", "core": true, "findings": [], "data": {}},
        "ptr": {"status": "fail", "core": true, "findings": [], "data": {}}
      },
      "not_checked": [
        {"check": "dkim_signature", "reason": "needs_a_message"},
        {"check": "alignment", "reason": "needs_a_message"}
      ],
      "diff": {
        "baseline": {"id": "ir_01JB2...", "checked_at": "2026-10-24T12:00:00Z"},
        "first_run": false,
        "changed": true,
        "worsened": true,
        "status_from": "pass",
        "score_from": 100,
        "changes": [
          {"path": "dkim.key.mail.sha256", "section": "dkim", "kind": "removed",
           "severity": "critical", "effect": "worsened", "from": "9f2c...", "to": null}
        ],
        "not_compared": [
          {"path": "blocklist_ip.203.0.113.5.bl.spamcop.net.listed", "reason": "lookup_failed"}
        ]
      }
    }
  3. ضعه في cron

    باستخدام diff=true، تُقارَن كل عملية تشغيل بآخر عملية لديك، ويحوّل jq الإجابة إلى رمز خروج.

    الطلب

    # exits non-zero if the domain is broken or its setup changed
    curl -s 'https://email-spam-tester.com/api/v1/infra/check?domain=example.com&selector=mail&diff=true' \
      | jq -e '.ok and (.diff.changed | not)'
domainمطلوب. يقبل ما تقبله الأدوات: نطاقًا، أو عنوان URL، أو عنوان بريد إلكتروني.
ipعنوان الإرسال الخاص بك. كرّره لإضافة المزيد، حتى 6.
selectorمحدِّد DKIM. كرّره لإضافة المزيد، حتى 10. يجب أن يكون كل محدِّد تمرّره موجودًا، وإلا يفشل قسم dkim.
heloالاسم الذي يقدّمه خادمك في HELO، مقارنةً بسجل PTR الخاص به.
accountالجهة التي يخصّها الطلب. مطلوب مع مفتاح يخدم عدة أشخاص.
checksالأقسام المطلوب تشغيلها، مفصولة بفواصل. تُشغّل جميعها افتراضيًا.
diffتقارن true هذا التشغيل بآخر تشغيل لك للنطاق.
since7d أو 12h أو تاريخ بتنسيق ISO 8601. تقارن بالتشغيل الأقرب إلى تلك اللحظة ضمن 12 ساعة، وإلا فبآخر تشغيل قبلها. تفعّل diff.
baselineمعرّف أحد تشغيلاتك للمقارنة به. يفعّل diff.
freshتتجاوز true ذاكرة التخزين المؤقت البالغة مدتها 60 ثانية.

قراءة الإجابة

تُرجع عملية الفحص المكتملة 200، وتكون النتيجة في النص. status هو أسوأ حالة في الأقسام المطلوبة: spf وdkim وdmarc وptr وblocklist_ip وblocklist_domain وmx وsmtp. تُحتسب unknown في قسم مطلوب على أنها warn. تكون ok بقيمة true عندما تكون status هي pass أو warn. تتراوح score من 0 إلى 100 عبر الأقسام المطلوبة التي أعادت إجابة، وتكون null عندما تؤدي الأخطاء والقيم unknown إلى ترك أقل من نصف الوزن المنطبق. يتم الإبلاغ عن mta_sts وtls_rpt وbimi وdnssec وdane وns وregistration ومقارنتها، لكنها لا تؤثر في ok أو score.

يمكن أن تكون حالة القسم pass أو warn أو fail أو error (تعذّر علينا الفحص) أو unknown (المعلومات المتاحة غير كافية) أو skipped (لا ينطبق). لا تؤثر skipped في النتيجة، ويوجد السبب في not_checked. تكون dkim_signature وalignment موجودتين دائمًا، لأنهما تحتاجان إلى رسالة حقيقية.

ما الذي يغيّره ip وselector

يتعلق PTR وقوائم الحظر بالعناوين، لذلك تحتاج عملية الفحص إلى بعضها. تستخدم قيم ip التي تمررها. إذا لم تمرر أيًا منها، فتأخذ ما يصل إلى أربعة عناوين من مضيفي MX لديك ومن حدود ip4: وip6: ذات العنوان الواحد في سجل SPF الجذري. تُدرج عناوين مزوّد بريد معروف على أنها managed وتُترك دون فحص، وإذا لم يتبق شيء فتُرجع ptr وblocklist_ip الحالة skipped. لا يمكن قراءة selector من DNS، لذلك تجرّب عملية الفحص القيمة التي تقدمها، والقيم التي عثرت عليها عمليات الفحص السابقة، وقائمة من الأسماء الشائعة. عدم العثور على شيء لا يثبت شيئًا، وتُرجع dkim الحالة unknown. إذا كنت ترسل من خادمك الخاص، فمرّر كليهما.

ما الذي تغيّر

يحتوي كل إدخال في diff.changes على path، وkind (added، وremoved، وchanged)، وseverity (critical، وwarning، وinfo)، وeffect (worsened، وimproved، وneutral). لا تضبط سوى critical وwarning القيمة diff.changed، لذلك لا يؤدي تدوير مفتاح DKIM إلى مفتاح بالطول نفسه، أو إضافة عنوان MX جديد، أو تجديد شهادة، إلى فشل سطر cron. تتبع diff.worsened قيمة effect لأي تغيير. عند التشغيل الأول، لا يوجد ما يمكن مقارنته، وتشير diff.first_run إلى ذلك.

يكون خط الأساس دائمًا عملية فحص خاصة بك، لذلك فإن فحص شخص آخر للنطاق بين عمليتي فحص خاصتين بك لا يخفي شيئًا. ينتقل أي شيء لم نتمكن من قراءته هذه المرة إلى diff.not_compared مع الاحتفاظ بآخر قيمة معروفة له، ما يعني أن التغيير الذي أُجري أثناء انقطاع يظهر بمجرد أن تعمل عملية البحث مجددًا. تبقى عملية الفحص التي تستخدم ip أو selector مختلفًا ضمن السلسلة نفسها، وما لم تطلب فحصه لا تتم مقارنته أيضًا.

لماذا ينبغي أن يستخدم الفحص المجدول مفتاحًا

من دون مفتاح، يرتبط سجلك بتجزئة ذات مفتاح لعنوان IP الخاص بك، لذلك ينتهي عندما يتغير العنوان، ويتشاركه الأشخاص الموجودون خلف عنوان واحد: تنقل عملية فحص يجريها زميل خط الأساس الخاص بك. عند استخدام مفتاح API شخصي في Authorization: Bearer، يتبع السجل المفتاح. تُحفظ عمليات الفحص التي تستخدم مفتاحًا لمدة 365 يومًا ولا تُفتح إلا بذلك المفتاح. تُحفظ العمليات التي لا تستخدم مفتاحًا لمدة 30 يومًا ويمكن لأي شخص لديه معرّفها فتحها.

6 طلبات في الدقيقة و50 طلبًا في اليوم لكل IP، أو 30 و500 لكل مفتاح. بعد تجاوز ذلك تكون الإجابة 429 مع Retry-After. يأتي الطلب المطابق خلال 60 ثانية من ذاكرة التخزين المؤقت، ويُعلَّم بالقيمة cached: true، ولا يكتب عملية فحص ولا يُحتسب. تسمح قراءة عمليات الفحص المخزنة بـ120 طلبًا في الدقيقة لكل عميل. تعني 503 مع Retry-After أن عددًا كبيرًا جدًا من عمليات الفحص قيد التشغيل، أو، عند قراءة عمليات الفحص المخزنة، أن التخزين غير متاح. تعني 401 أن المفتاح غير صحيح. تحمل 422 القيمة detail.code: invalid_domain أو invalid_ip أو invalid_selector أو invalid_check أو invalid_since أو unknown_baseline أو account_required.

نقاط النهاية

GET/api/v1/infra/check

يشغّل الفحص. المعلمات موجودة في الجدول أعلاه.

GET/api/v1/infra/runs/{public_id}

تشغيل واحد مخزّن، بالكامل. يعيد 404 إذا لم يكن موجودًا أو كان تابعًا لمفتاح آخر.

GET/api/v1/infra/domains/{domain}/runs

تشغيلاتك لنطاق، من الأحدث إلى الأقدم: المعرّف، والوقت، والحالة، والنتيجة، وعدد التغييرات. يقبل limit (من 1 إلى 100، و30 افتراضيًا) وbefore، وهو معرّف تشغيل.

GET/api/v1/infra/diff

المقارنة نفسها بين تشغيلين مخزّنين، ?from=<id>&to=<id>. تحتاج إلى صلاحية الوصول إلى كليهما.

GET/api/v1/infra/checks

كل قسم مع وزنه، وإصدار النتيجة، والحدود.

فحوص فردية

يجيب كل استدعاء عن سؤال واحد ولا يحتفظ بأي سجل. تشغّل الأداة جزءًا واحدًا من فحص البنية التحتية بشكل مستقل، باستثناء أداة الترويسة، التي تقرأ رسالة سبق أن تلقيتها.

بدء سريع

  1. اختر فحصًا

    اختر الأداة من القائمة أدناه ومرّر النطاق أو العنوان أو IP الذي تطلبه.

    الطلب

    curl -s 'https://email-spam-tester.com/api/v1/tools/spf?domain=example.com'
  2. اقرأ الحالة والنتائج

    تجيب كل أداة بحالة ونتائجها. وتعتمد الحقول التي تليهما على الأداة.

    الاستجابة

    {
      "tool": "spf",
      "query": {"domain": "example.com"},
      "checked_at": "2026-10-31T12:00:00Z",
      "duration_ms": 412,
      "status": "fail",
      "findings": [
        {"code": "spf.too_many_lookups", "level": "fail",
         "params": {"limit": 10, "count": 12},
         "message": "RFC 7208 §4.6.4 allows at most 10 DNS lookups, and this record needs 12, so receivers return permerror."}
      ],
      "record": "v=spf1 include:_spf.example.net ~all",
      "lookups": {"count": 12, "limit": 10, "void": 0}
    }

نقاط النهاية

تُرجع جميعها 200 مع حالة وقائمة بالنتائج، ولكل نتيجة رمز ومعاملاته. تكون الحالة pass أو warn أو fail أو error، ويمكن أيضًا للأداة المشتركة مع فحص البنية التحتية أن تُرجع unknown أو skipped. البحث الذي تنتهي مهلته أو القائمة التي ترفض الاستعلام لا يُحتسب أبدًا كحالة pass. 30 طلبًا في الدقيقة و300 طلب في اليوم لكل IP عبر الأدوات؛ وما يزيد على ذلك تكون الاستجابة له 429 مع Retry-After.

GET/api/v1/tools/spf

سجل SPF لنطاق: بنيته، وكل تضمين وإعادة توجيه تتم متابعتهما، وعدد استعلامات DNS التي تتطلبها الشجرة بأكملها مقارنة بالحد الأقصى البالغ عشرة. مرّر ?domain=example.com.

GET/api/v1/tools/dmarc

سجل DMARC لنطاق، أو لنطاقه التنظيمي عندما لا يكون لديه سجل: الوسوم، والسياسة، وما إذا كان كل عنوان خارجي للتقارير قد وافق على تلقي التقارير. مرّر ?domain=example.com.

GET/api/v1/tools/dkim

مفتاح DKIM المنشور لمحدِّد: ما إذا كان موجودًا ويمكن فك ترميزه، ونوعه وحجمه، وعلامتا الإلغاء والاختبار. مرّر ?domain=example.com&selector=s1.

GET/api/v1/tools/blocklist

عنوان IPv4 أو عنوان IPv6 أو نطاق يُفحَص مقابل قوائم حظر DNS التي يستخدمها التقرير، مع إجابة كل قائمة. مرّر ?target=203.0.113.5.

GET/api/v1/tools/mx

سجلات MX لنطاق بالترتيب الذي يجرّبها به المرسلون، مع عناوين IPv4 وIPv6 لكل مضيف. يتم الإبلاغ عن MX الفارغ، والنطاق الذي لا يحتوي على MX، والمضيفين الذين يمثّلون عناوين IP أو CNAMEs، والمضيفين الذين لا يمكن تحليل أسمائهم، وكذلك سجلات MTA-STS وTLS-RPT. مرّر ?domain=example.com.

GET/api/v1/tools/bimi

إعداد BIMI لنطاق في أربع خطوات: سياسة DMARC التي يتطلبها BIMI، والسجل في default._bimi، وشعار SVG الذي تم التحقق منه وفق ملف تعريف Tiny PS، وشهادة العلامة مع نوعها ونطاقاتها وتاريخ انتهاء صلاحيتها. مرّر ?domain=example.com، و&selector= لمحدّد غير default.

GET/api/v1/tools/ptr

سجلات PTR لعنوان ما، وما إذا كان أي من هذه الأسماء يُحلّ عائدًا إليه. يؤدي فشل الاستعلام إلى الحالة error؛ ويؤدي غياب السجل إلى الحالة fail. مرّر ?ip=8.8.8.8.

GET/api/v1/tools/mta-sts

سجل MTA-STS لنطاق ما وملف السياسة الذي يشير إليه: الوضع، والمضيفون المدرجون، وأي مضيف MX تستبعده السياسة. مرّر ?domain=example.com.

GET/api/v1/tools/tls-rpt

سجل TLS-RPT لنطاق ما والعناوين التي تتلقى تقاريره. مرّر ?domain=example.com.

GET/api/v1/tools/dnssec

ما إذا كانت منطقة نطاق ما موقّعة أو غير موقّعة أو معطّلة، استنادًا إلى سجلات DNSKEY وDS الخاصة بها. يُميَّز التوقيع غير الصالح عن انقطاع خدمة المُحلِّل. مرّر ?domain=example.com.

GET/api/v1/tools/dane

سجلات TLSA لمضيفي MX، مقارنةً بالشهادة التي يقدمها المضيف عندما يكون من الممكن قراءة تلك الشهادة. مرّر ?domain=example.com.

GET/api/v1/tools/smtp

STARTTLS والشهادة على أول مضيفين من مضيفي MX: إصدار TLS، والجهة المُصدِرة، وتاريخ انتهاء الصلاحية، وما إذا كانت السلسلة والاسم صالحين. نتصل فقط بالمضيفين التابعة للنطاق الذي طلبته ونتخطى مزودي البريد، وتُشارك نتيجة واحدة لكل عنوان لمدة 6 ساعات. لا يُرسل أي بريد. مرّر ?domain=example.com.

GET/api/v1/tools/ns

خوادم الأسماء لنطاق ما وما إذا كانت منطقته تحتوي على سجل SOA. وجود خادم أسماء واحد يُعد تحذيرًا. مرّر ?domain=example.com.

GET/api/v1/tools/registration

موعد انتهاء تسجيل نطاق ما، من RDAP. تبقي أقل من 30 يومًا يُعد تحذيرًا. المنطقة التي لا تتوفر لها خدمة RDAP تُرجع skipped. مرّر ?domain=example.com.

POST/api/v1/tools/header

رؤوس رسالة مستلمة، تُرسل بصيغة JSON {"headers": "..."} أو بصيغة text/plain: المسار من قفزة إلى أخرى مع التأخيرات وTLS وانحراف الساعة، وAuthentication-Results الخاصة بالمستلِم، ومحاذاة نطاقات From وDKIM d= وReturn-Path، ورؤوس DKIM وARC وإلغاء الاشتراك وعامل تصفية الرسائل غير المرغوب فيها. يتم إسقاط كل ما يأتي بعد أول سطر فارغ من دون قراءته. تتم معالجة الرؤوس في الذاكرة ولا يتم تخزينها أو وضعها في ذاكرة التخزين المؤقت أو تسجيلها.

تحقق من النطاق كل ليلة.
اختبر رسالة البريد الإلكتروني قبل إرسالها.

مشترك بين جميع المنتجات

الوصول، والمفاتيح، وتنسيق التقرير، والحالات، والأخطاء، بالإضافة إلى OpenAPI وllms.txt للأنظمة الآلية.

المصادقة

لا توجد مصادقة. لا مفتاح لطلبه، ولا ترويسة لتعيينها، ولا حساب لإنشائه. المعرّف المختصر الذي تحصل عليه هو صلاحية الوصول: يمكن لمن يحمله قراءة ذلك التقرير، ولا يمكن لأي شخص آخر تخمينه.

وهذا يعني أيضًا أن المعرّف المختصر يستحق أن تعامله ككلمة مرور. يعرض التقرير سطر الموضوع والمرسل وعنوان الارتداد والمصدر الكامل للرسالة لأي شخص يحمل الرابط.

مفاتيح API الشخصية

Everything above works without a key. A key is for automation platforms such as Zapier, where every user's calls come from the platform's servers and per-IP limits would be shared by all of them. With a key, limits count per key (50 tests a day, 3 with placement, 5 permanent mailboxes), the key's tests form a history, and the key can keep permanent mailboxes whose reports only it can read. Send the key as Authorization: Bearer est_live_… on any call on this page. The routes below also take account, a short name of your choosing ([A-Za-z0-9_-], up to 64 characters) that keeps separate lists under one key. GET /api/v1/installations/tests requires it; pass the same one on POST /api/v1/inbox so the test shows up there. The Zapier integration uses zapier.

POST /api/v1/keys

Send JSON {"email":"you@example.com"}. Returns HTTP 201 with key and email. The key is shown once; only its hash is kept. Asking again gives a new key and leaves the earlier ones working. Limit: 5 keys per IP per UTC day. The form on /zapier/ calls this.

GET /api/v1/keys/me

Returns email, key_prefix and created_at of the key in the header, or HTTP 401. Use it to check a key.

GET /api/v1/installations/tests

The key's tests, newest first: ?account=…&limit=50 (up to 100), and before=<slug> for the next page. Each item has slug, created_at, analysis_status (waiting or expired before an email arrived), score_ours, score_compat, placement and changes, the checks that moved since the previous test of the same sending domain. Read the full report at /api/v1/tests/{slug}.

POST /api/v1/installations/mailboxes

Send JSON {"domain":"example.com","account":"…"}. Returns the permanent mailbox of that sending domain: id, address, domain, state, daily_cap and created. HTTP 201 when it is new, 200 when it already existed, 409 when the key keeps as many mailboxes as it may. Subscribe the address to a newsletter or a sequence and every email that arrives is checked. GET on the same path with ?account=… lists them, and DELETE /api/v1/installations/mailboxes/{mailbox_id} stops one.

GET /api/v1/installations/mailboxes/{mailbox_id}/letters

The emails that arrived, oldest first, paged with after_id and next_after_id. settled=true ends the page before the first email still being checked, so paging never skips one. newest=true turns the order round, for a quick look at the latest; settled does nothing with it. Each has test_id, slug, received_at, analysis_status, score_ours, score_compat, subject, from_addr and kind.

GET /api/v1/installations/letters/{slug}

The report of one email in a permanent mailbox, the same JSON as /api/v1/tests/{slug} with report_url null: there is no public page for it. HTTP 410 once the report has expired.

قراءة التقرير

الحقول التي تحمل الإجابة، بالترتيب الذي يُرجّح أنك تريده.

score_oursمن 0 إلى 100. نموذجنا. تحمل المصادقة والبنية التحتية معظم الوزن، لأنهما تحددان التسليم قبل أن يقرأ عامل تصفية كلمة واحدة من النص.
score_compatمن 0 إلى 10. يعيد إنتاج الرقم بأسلوب SpamAssassin الذي يقارنه الأشخاص بالفعل، بحيث يكون التقرير قابلاً للمقارنة بما رآه شخص ما في مكان آخر.
subscoresالمقياس نفسه من 0 إلى 100 لكل قسم: auth، وinfra_spam، وcontent، وcompliance.
checks[]جميع الفحوصات البالغ عددها 42، ولكل منها حالة، ونتيجة في سطر واحد، والأدلة التي استند إليها القرار، ومقدار ما خصمته من الدرجتين.
checks[].citationsمصدر النتيجة: القسم من RFC، مقتبسًا حرفيًا، والصفحة التي تذكر فيها Google متطلبها الخاص. جُمعت يدويًا بدلًا من إنشائها آليًا، لذا يمكن الاعتماد عليها.
الإصلاحات[]ما يجب تغييره، بالترتيب، مع النقاط التي يستحقها كل تغيير. تُحسب المكاسب بإعادة تقييم التقرير، ولا تُقدّر تقديرًا.
مكتملتكون القيمة خطأ عندما يتعذر تشغيل فحص. العنصر الذي لم يُفحص لا يُعد ناجحًا أبدًا، لذا تعامل مع النتيجة على أنها متفائلة حتى تصبح القيمة صحيحة.
رابط_التقريرالصفحة المقروءة للبشر. أعطها لشخص بدلًا من جدار من JSON.

الحالات

يكون الفحص واحدًا من خمسة أشياء، والفرق بين اثنين منها أهم مما يبدو.

ناجحتم تشغيل الفحص ولم يجد أي خطأ.
تحذيريستحق الإصلاح. يكلّف نقاطًا.
فاشلسيضرّ بقابلية التسليم. يكلّف نقاطًا أكثر.
تخطيلم ينطبق. لا توجد مرفقات لفحصها، ولا جزء HTML لتقييمه. لا يُعد نجاحًا.
خطألم نتمكن من معرفة ذلك. يُستبعد من النتيجة ويُعلَّم، بدلًا من احتسابه نجاحًا.

يمر analysis_status بالقيم received وanalyzing وchecks_ready وfailed. ويمر ai_status بالقيم pending وrunning وready وfallback وerror. يصبح التقرير الحتمي نهائيًا عند checks_ready؛ ولا يضيف ai_status سوى الخطة.

ما يمكن أن يعود

202العنوان محجوز ولم تصل أي رسالة. يتضمن المتن العنوان ووقت انتهاء الصلاحية واللغة، بحيث يظل بإمكان المستدعي الذي لم ينشئ الحجز عرضه.
404لا توجد معرّفة مختصرة كهذه. إما أنها لم توجد قط، أو أن الحجز قد نُسي.
410انتهت صلاحية العنوان قبل وصول رسالة.
409حاولت تغيير اللغة بعد وصول الرسالة بالفعل.
429حد الاختبارات المجانية لعنوانك. لا يوجد حالياً حد لكل شخص في هذه الخدمة؛ وإذا وُضع حد في أي وقت، فسيبيّن المتن وقت إعادة تعيينه.

أربعة أمور يجدر معرفتها

رسالة واحدة لكل عنوان

تُرفض الرسالة الثانية. يبقى تقريرك السابق كما هو، وهذا هو المقصود.

ساعة واحدة لاستخدامه

تنتهي صلاحية العنوان؛ أما التقرير فلا. روابط التقارير دائمة، لذا يستمر عمل أي رابط يُلصق في تذكرة.

أرسل من المنصة

اختبار حملة من حساب شخصي يقيس ذلك الحساب. كل ما في قسم المصادقة تقريبًا يتعلق بالبنية التحتية للإرسال، لا بالنص.

أعد الاختبار بعد الإصلاح

تُحسب التحسينات المتوقعة لكل إصلاح على حدة، ولا تتراكم. التقرير الثاني هو الرقم الفعلي.

للأنظمة الآلية

GET/api/health

فحص الحيوية. بلا مصادقة، وبلا آثار جانبية.

جرّب واحدًا يدويًا أولًا

يستغرق الأمر نحو دقيقة ويوضح لك بالضبط ما يصفه JSON.

احصل على عنوان اختبار

البيئة المعزولة.

كل نقطة نهاية مزودة بزر يشغّلها على الخدمة الفعلية. لا يتطلب أي شيء هنا مفتاحًا، لذا فإن أي طلب ترسله من هذه الصفحة هو طلب حقيقي: فهو يحجز عنوانًا حقيقيًا ويُحتسب.

جرّبه في البيئة المعزولة