تخطَّ إلى المستندات
API

تحديث نطاق

يضبط نطاق التتبع المخصّص ونطاق الملفات المخصّص للنطاق أو يعيد فحصهما أو يزيلهما، وهما الشيئان الوحيدان في النطاق اللذان تستطيع هذه الـ API تغييرهما.

PATCHapi.openemail.uk/domains/{id}

ينفّذ الاستدعاء الحقيقي على مساحة عملك، بمفتاحك أنت.

PATCH /domains/{id}

يضبط نطاق التتبع المخصّص ونطاق الملفات المخصّص للنطاق أو يعيد فحصهما أو يزيلهما، وهما الشيئان الوحيدان في النطاق اللذان تستطيع هذه الـ API تغييرهما.

الطلب

يمكن أن يكون للنطاق نطاق تتبع مخصّص واحد ونطاق ملفات مخصّص واحد، كلٌّ منهما نطاق فرعي منه تختاره أنت، مثل links.acme.com وfiles.acme.com، وذلك بمجرد أن يصير موثّقًا أو يُنشر سجل _openemail-challenge من نوع TXT الخاص به. ولا يلزم أن يكون مستقبِلًا للبريد بعد. وضبط أحدهما يجهّز عنوانًا لذلك الاسم وحده، يُبلَّغ عنه في target، وrecord هو سجل CNAME الذي يوجّه الاسم إليه. وبمجرد نجاح فحص، تستخدم الروابط المتتبَّعة وبكسل الفتح في البريد الجديد من النطاق https://links.acme.com/t/...، وتستخدم روابط تنزيل الملفات المرسلة منه https://files.acme.com/f/...، بدلًا من المضيف الافتراضي.

المعاملات

trackingHoststring | null
النطاق الفرعي المستخدَم للروابط المتتبَّعة ولبكسل الفتح، بحد أقصى 512 حرفًا. تُقتطع مسافاته ويُحوَّل إلى أحرف صغيرة، ويُزال منه `https://` أو `http://` في المقدمة وأي مسار وأي نقطة في النهاية قبل فحصه. والقيمة الجديدة تحل محل نطاق التتبع الحالي، والقيمة الحالية تُعيد تشغيل الفحص، و`null` أو سلسلة فارغة تزيله، وترك الحقل يتركه كما هو.
storageHoststring | null
النطاق الفرعي المستخدَم لروابط تنزيل الملفات، يُنظَّف بالطريقة نفسها ويخضع لحد الـ 512 حرفًا نفسه. والقيمة الجديدة تحل محل نطاق الملفات الحالي، والقيمة الحالية تُعيد تشغيل الفحص، و`null` أو سلسلة فارغة تزيله، وترك الحقل يتركه كما هو.

جسم الطلب صارم في المفاتيح ومتساهل في عددها. فأي مفتاح غير trackingHost وstorageHost هو 422 unknown_parameter، وجسمٌ لا يحمل أيًّا منهما عملية لا أثر لها تُجيب بـ 200 ومعها النطاق كما هو. ويمكن إرسالهما معًا في استدعاء واحد، ويُطبَّقان بالترتيب، trackingHost أولًا: فرفض trackingHost يوقف الاستدعاء قبل مسّ storageHost، ورفض storageHost يترك تغيير trackingHost الذي تم بالفعل قائمًا. أرسِلهما منفصلين حين يجب أن يستقل أحدهما بنفسه.

ضبط نطاق تتبع ونطاق ملفات

يتطلب domains:write. ويُتحقق من كل مضيف ويُحفظ ويُفحص في الاستدعاء نفسه، فتحمل الاستجابة نتيجة ذلك الفحص الأول بالفعل. وهي جسم GET /domains/{id} نفسه.

curl
curl -X PATCH "$OE/domains/b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f" -H "$AUTH" -H "Content-Type: application/json" \  -d '{ "trackingHost": "links.acme.com", "storageHost": "files.acme.com" }'
الاستجابة
{  "object": "domain",  "id": "b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f",  "domain": "acme.com",  "receiving": {    "verified": true,    "verifiedAt": "2026-08-14T10:02:00.000Z",    "catchAll": false,    "lastCheckedAt": "2026-08-29T06:00:00.000Z",    "error": null  },  "sending": {    "status": "verified",    "canSend": true,    "checkedAt": "2026-08-29T06:00:00.000Z",    "error": null,    "note": "Mail from this domain is signed and can be sent."  },  "tracking": {    "host": "links.acme.com",    "status": "pending",    "active": false,    "target": "oelinks3f9a1c7e2b8d4a60.edge.openemail.uk",    "record": { "type": "CNAME", "name": "links.acme.com", "value": "oelinks3f9a1c7e2b8d4a60.edge.openemail.uk" },    "checkedAt": "2026-08-29T06:05:12.000Z",    "verifiedAt": null,    "error": "links.acme.com does not resolve yet. Add a CNAME record named links.acme.com with the value oelinks3f9a1c7e2b8d4a60.edge.openemail.uk, then check again."  },  "storage": {    "host": "files.acme.com",    "status": "pending",    "active": false,    "target": "oefiles81c40d6b2f7e9a35.edge.openemail.uk",    "record": { "type": "CNAME", "name": "files.acme.com", "value": "oefiles81c40d6b2f7e9a35.edge.openemail.uk" },    "checkedAt": "2026-08-29T06:05:12.000Z",    "verifiedAt": null,    "error": "files.acme.com does not resolve yet. Add a CNAME record named files.acme.com with the value oefiles81c40d6b2f7e9a35.edge.openemail.uk, then check again."  },  "addresses": [    { "address": "[email protected]", "enabled": true }  ],  "createdAt": "2026-08-14T09:55:11.000Z"}

انشر tracking.record وstorage.record لدى مزوّد DNS كسجلي CNAME عاديين، مع إيقاف أي وساطة. يحلّ الفحص كل اسم، ثم يطلب من https://links.acme.com/t/v/<nonce> أو https://files.acme.com/f/v/<nonce> جوابًا موقّعًا من OpenEmail. وإعادة التوجيه تُفشل الفحص، وكذلك قد يفعل وسيط أمام الاسم.

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

إن تعذّر تجهيز العنوان أثناء الاستدعاء، تكون record فارغة وtarget سلسلة فارغة وerror تقول إنه قيد التجهيز. وينتهي ذلك خلال دقائق قليلة دون استدعاء آخر، فاقرأ النطاق من جديد عبر GET /domains/{id} للحصول على السجل.

الاسمان مستقلان. فالاستدعاء الذي يحمل حقلًا واحدًا يترك الكائن الآخر تمامًا كما كان، ولذلك فإن إعداد الملفات لاحقًا لا يزعج أبدًا نطاق تتبع يعمل بالفعل.

أعد الفحص، أو أزِله

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

curl
curl -X PATCH "$OE/domains/b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f" -H "$AUTH" -H "Content-Type: application/json" \  -d '{ "trackingHost": null }'
tracking، بعد الإزالة
{  "host": null,  "status": "none",  "active": false,  "target": "",  "record": null,  "checkedAt": null,  "verifiedAt": null,  "error": null}

الروابط في البريد المرسَل بالفعل تحتفظ بالمضيف الذي خرجت به، وهذا يشمل رابط التنزيل على ملف بقدر ما يشمل رابطًا متتبَّعًا. وبعد أن تزيل اسمًا أو تغيّره، تظل تلك الروابط تعمل ما دام سجل CNAME القديم قائمًا. وقد يعطي إعداد اسم من جديد قيمة record مختلفة، فانشر ما تبلّغ به الاستجابة.

كائن tracking

hoststring | null
نطاق التتبع، أو null حين لا يكون للنطاق واحد.
status'none' | 'pending' | 'active' | 'failed'
`none` تعني ألا نطاق تتبع مضبوط. و`pending` تعني أن واحدًا مضبوط ولم يجتز فحصًا قط. و`active` تعني أن البريد الجديد يستخدمه. و`failed` تعني أنه اجتاز فحصًا من قبل ثم خرج من الاستخدام.
activeboolean
صحيحة تمامًا حين تكون `status` هي `active`، أي حين تستخدم الروابط المتتبَّعة وبكسل الفتح في البريد الجديد من النطاق ذلك المضيف.
targetstring
العنوان الذي يشير إليه سجل CNAME، مجهّز لنطاق التتبع هذا وحده. وهو سلسلة فارغة ما دامت `host` فارغة، وكذلك ما دام العنوان الخاص بمضيف جديد قيد التجهيز.
record{ type: 'CNAME'; name: string; value: string } | null
السجل الواجب نشره، باسم `host` وقيمته `target`. وهو null حين لا يوجد نطاق تتبع، وكذلك ما دام العنوان الخاص بمضيف جديد قيد التجهيز.
checkedAtstring | null
متى فُحص المضيف آخر مرة، بصيغة ISO-8601. وهو null حتى أول فحص.
verifiedAtstring | null
متى اجتاز فحصًا آخر مرة، بصيغة ISO-8601. وهو null لمضيف لم يجتز فحصًا قط.
errorstring | null
ما وجده آخر فحص، بكلمات يستطيع مالك النطاق التصرف بناءً عليها. وهو null حين ينجح آخر فحص أو حين لم يُجرَ أي فحص بعد. والمضيف الذي أخفق في فحص أو فحصين يظل `active` ويحمل السبب هنا.

كائن storage

يبلّغ نطاق الملفات في storage، بالحقول نفسها تمامًا كما في tracking. ولا يختلف إلا ما يُستخدم فيه الاسم: فـ active هناك تعني أن روابط تنزيل الملفات المرسلة من النطاق تشير إليه.

hoststring | null
نطاق الملفات، أو null حين لا يكون للنطاق واحد.
status'none' | 'pending' | 'active' | 'failed'
`none` تعني ألا نطاق ملفات مضبوط. و`pending` تعني أن واحدًا مضبوط ولم يجتز فحصًا قط. و`active` تعني أن البريد الجديد يستخدمه. و`failed` تعني أنه اجتاز فحصًا من قبل ثم خرج من الاستخدام.
activeboolean
صحيحة تمامًا حين تكون `status` هي `active`، أي حين تستخدم روابط تنزيل الملفات المرسلة من النطاق ذلك المضيف.
targetstring
العنوان الذي يشير إليه سجل CNAME، مجهّز لنطاق الملفات هذا وحده. وهو سلسلة فارغة ما دامت `host` فارغة، وكذلك ما دام العنوان الخاص بمضيف جديد قيد التجهيز.
record{ type: 'CNAME'; name: string; value: string } | null
السجل الواجب نشره، باسم `host` وقيمته `target`. وهو null حين لا يوجد نطاق ملفات، وكذلك ما دام العنوان الخاص بمضيف جديد قيد التجهيز.
checkedAtstring | null
متى فُحص المضيف آخر مرة، بصيغة ISO-8601. وهو null حتى أول فحص.
verifiedAtstring | null
متى اجتاز فحصًا آخر مرة، بصيغة ISO-8601. وهو null لمضيف لم يجتز فحصًا قط.
errorstring | null
ما وجده آخر فحص، بكلمات يستطيع مالك النطاق التصرف بناءً عليها. وهو null حين ينجح آخر فحص أو حين لم يُجرَ أي فحص بعد. والمضيف الذي أخفق في فحص أو فحصين يظل `active` ويحمل السبب هنا.

كيف يُفحص المضيف

يُفحص الاسمان على الجدول نفسه، ويُفحص كلٌّ منهما على حدة.

  • المضيف الذي لم يجتز فحصًا بعد يُفحص كل دقيقتين في ساعته الأولى، وكل 10 دقائق في يومه الأول، وكل ساعة في أسبوعه الأول، وكل 6 ساعات بعد ذلك.
  • المضيف النشط يُفحص كل 10 دقائق، ويُعاد الفحص المخفق عليه بعد دقيقة ثم بعد دقيقتين.
  • يتوقف استخدام المضيف النشط بعد ثلاثة فحوص مخفقة متتالية، أو بمجرد أن يتجاوز عمر آخر فحص ناجح ساعتين. ويعود البريد الجديد عندئذ إلى المضيف الافتراضي، وتصير status هي failed حتى ينجح فحص من جديد. وتستمر الفحوص، متباعدة أكثر في كل مرة وبفاصل لا يتجاوز ساعة.

نطاق التتبع يخدم مسارات التتبع فقط، ونطاق الملفات يخدم مسارات التنزيل فقط، ولا يجيب أيٌّ منهما إلا عن بريد أرسلته مساحة العمل المالكة له.

الأخطاء

الحالةtypecodeمتى
400invalid_request_errormalformed_jsonجسم الطلب ليس JSON صالحًا.
403permission_errorinsufficient_scopeالمفتاح لا يحمل domains:write.
404not_found_errorresource_not_foundلا يوجد نطاق بهذا المعرّف في مساحة العمل هذه.
409conflict_errordomain_not_verifiedأُرسل مضيف جديد بينما receiving.verified خاطئة وسجل _openemail-challenge من نوع TXT للنطاق غير منشور بعد. وparam هي الحقل الذي ورد فيه، trackingHost أو storageHost.
409conflict_errortracking_host_in_useنطاق آخر يستخدم المضيف بالفعل كنطاق تتبع له، أو المضيف مستخدَم بالفعل كنطاق ملفات، أو نطاق التتبع الخاص بالنطاق يديره خادم OpenEmail آخر. وparam هي trackingHost.
409conflict_errorstorage_host_in_useالحالات الثلاث نفسها لنطاق الملفات: نطاق آخر يستخدم المضيف بالفعل كنطاق ملفات له، أو المضيف مستخدَم بالفعل كنطاق تتبع، أو نطاق الملفات هنا يديره خادم OpenEmail آخر. وparam هي storageHost.
422validation_errorinvalid_tracking_hostالمضيف ليس اسم مضيف صالحًا، أو أنه غير مسموح به: إذ يجب أن يكون نطاقًا فرعيًا صريحًا من النطاق، ولا يمكن أن يكون مضيف مسار الارتداد bounce.<domain> ولا اسمًا يخص OpenEmail ولا نطاقًا مُعدًّا لاستقبال البريد. وparam هي trackingHost.
422validation_errorinvalid_storage_hostالقواعد نفسها، مرفوضة على نطاق الملفات. وparam هي storageHost.
422validation_errorunknown_parameterمفتاح في جسم الطلب غير trackingHost وstorageHost.
422validation_errorinvalid_parameterجسم الطلب ليس كائن JSON، أو أن حقلًا موجودًا فيه ليس سلسلة ولا null، أو يتجاوز 512 حرفًا. أما الجسم الذي لا يحمل أي حقل منهما فليس خطأً: فهو لا يغيّر شيئًا ويعود بـ 200.
422validation_errorcapability_unsupportedالمفتاح مقيَّد بعناوين مفردة لا بهذا النطاق كله، وكلا الاسمين يسري على كل عنوان في النطاق. والمفتاح الذي يحمل النطاق في domainAllowlist يستطيع ضبطهما. وparam هي domainAllowlist.