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

منح عنوان وسحبه

المحور الثاني: أي العناوين يستطيع شخص واحد الوصول إليها، وبأي مستوى.

POSTapi.openemail.uk/members/{userId}/addresses

ينفّذ أيًّا من الاستدعاءات الـ2 في هذه الصفحة على مساحة عملك، بمفتاحك أنت.

POST /members/{userId}/addresses

المحور الثاني: أي العناوين يستطيع شخص واحد الوصول إليها، وبأي مستوى.

المنح ليس دورًا

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

دورهمنحه على billing@هل يستطيع الإرسال باسم billing@
يملك `emails:send`memberنعم.
يملك `emails:send`viewerلا، المنح يرفض ذلك.
بلا `emails:send`memberلا، الدور يرفض ذلك.
يملك `emails:send`بلا أي منحلا، العنوان لا يدخل أصلًا في القائمة التي يُفحَص الإرسال في مقابلها.

إعطاء شخص دورًا لا يعطيه أي عناوين. العضو الذي يحمل دورًا بلا منح يفتح صندوق بريد فارغًا بدلًا من صندوق الجميع، وهو الإخفاق الصحيح الذي تريده وأنت ما زلت تقرر ما ينبغي أن يراه.

منح عنوان

يتطلب members:write. استخدم POST /members/{userId}/addresses مع { addressId, access }؛ وقيمة access الافتراضية هي member. يُعيد العضو كاملًا بحالته الجديدة.

curl
curl -X POST "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t/addresses" -H "$AUTH" \    -H "Content-Type: application/json" \    -d '{ "addressId": "c40a95f2-1cc6-4d31-82a8-9e075d31c2a8", "access": "viewer" }'
الاستجابة
{    "object": "member",    "userId": "nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t",    "email": "[email protected]",    "name": "Sam Okonjo",    "image": null,    "role": {      "id": "role_2b81de079c1f0a4b7e05d386",      "name": "Support",      "builtin": null    },    "implied": false,    "permissions": ["emails:send", "emails:read", "threads:read", "threads:write"],    "addresses": [      {        "addressId": "2b81de07-9c1f-4a4b-8e05-d3862c1f0a44",        "address": "[email protected]",        "access": "member"      },      {        "addressId": "c40a95f2-1cc6-4d31-82a8-9e075d31c2a8",        "address": "[email protected]",        "access": "viewer"      }    ],    "createdAt": "2026-08-12T14:20:00.000Z"  }

POST على المجموعة الفرعية بدلًا من PUT على الزوج، لأنها عملية إدراج أو تحديث في الحالتين، ولأن معرّف الصف ليس شيئًا يسمّيه المُنادي يومًا. وإعادة الإرسال بقيمة access مختلفة هي الطريقة التي يصير بها الـ viewer عضوًا: هناك صف واحد لكل (عنوان، شخص)، فالنداء الثاني يغيّر المستوى بدلًا من إضافة منح ثانٍ. وهذا أيضًا ما يجعلها الـ POST النادر الذي يأمن تكراره.

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

يعود العضو كاملًا بدلًا من المنح وحده، حتى يمكن إعادة رسم الصف على الشاشة دون طلب ثانٍ، وحتى تُقرأ الإجابة على النحو نفسه سواء كان المنح جديدًا أم تعديلًا.

العنوان الذي لا ينتمي إلى مساحة العمل هذه هو member_not_found، وهو 422، يحمل param: "addressId". فالمفتاح لا يستطيع توزيع سوى العناوين التي تخص مساحة العمل التي صدر مقابلها.

المنح لمالك مساحة العمل هو member_is_owner، وهو 422. فهو يملك أصلًا كل عنوان عليها، ولا شيء يمكن أن يضيفه هذا النداء.

سحب عنوان

يتطلب members:write. استخدم DELETE /members/{userId}/addresses/{addressId}. يُعيد العضو ناقصًا ذلك العنوان.

curl
curl -X DELETE \    "$OE/members/nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t/addresses/c40a95f2-1cc6-4d31-82a8-9e075d31c2a8" \    -H "$AUTH"
الاستجابة
{    "object": "member",    "userId": "nQ8vBz1aRd4tYwKx7fQ2mN8vBz1aRd4t",    "email": "[email protected]",    "name": "Sam Okonjo",    "image": null,    "role": {      "id": "role_2b81de079c1f0a4b7e05d386",      "name": "Support",      "builtin": null    },    "implied": false,    "permissions": ["emails:send", "emails:read", "threads:read", "threads:write"],    "addresses": [      {        "addressId": "2b81de07-9c1f-4a4b-8e05-d3862c1f0a44",        "address": "[email protected]",        "access": "member"      }    ],    "createdAt": "2026-08-12T14:20:00.000Z"  }

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

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

يعود العضو بدلًا من شاهدة حذف، لأن الجواب المهم هو ما يزال بإمكانه الوصول إليه. و{ deleted: true } هنا كانت ستترك العميل ليستنتج ذلك بالطرح.

لاسترداد كل شيء دفعة واحدة، يزيل DELETE /members/{userId} الدور وكل المنح معًا ويُبلغ بعدد ما أُزيل.