تخطَّ إلى المحتوى

المظاريف والمستلمون

المظروف عقد واحد في طريقه إلى التوقيع: إصدار قالب معروض بمتغيراتك، والمستلمون الذين يتعاملون معه، وأدلة على كل ما يحدث. أنشئ مظروفًا باستخدام POST /v1/envelopes.

الحقل النوع ملاحظات
template tpl_… إلزامي
version رقم أو "latest" الافتراضي latest؛ يُحدَّد ويُثبَّت عند الإنشاء. يجب أن يكون منشورًا
variables كائن يُتحقق منه وفق JSON Schema الخاص بالإصدار
recipients مصفوفة واحد لكل دور (role، name، email؛ واختياريًا externalUserId، verification، fields للتعبئة المسبقة حسب معرّف الحقل، order لتغيير ترتيب التوقيع)
subject، message سلسلة نصية تُستخدم في رسائل التوقيع وتُعرض على صفحة التوقيع
delivery email · embedded · none الافتراضي email
expiresAt RFC 3339 يجب أن يكون في المستقبل؛ تنتهي صلاحية المظروف حينها، وتتوقف روابط التوقيع وروابط المشاهدين عن العمل
cc مصفوفة مستلمو نسخ CC إضافيون (name، email) إلى جانب أدوار CC في القالب؛ حتى 50
viewers مصفوفة أشخاص يتابعون المظروف دون توقيع (name، email، واختياريًا notifyOnSignature)؛ عددهم لكل مظروف محدود حسب الخطة
viewerDocumentAccess قيمة منطقية السماح للمشاهدين بفتح المستند على صفحة الحالة الخاصة بهم. الافتراضي false (الحالة فقط)؛ خطة Team فما فوق
reminders كائن { "enabled": false } يوقف التذكيرات؛ { "enabled": true, "intervalHours": 24 } يغيّر الفاصل الزمني (من 1 إلى 720)
externalId سلسلة نصية معرّفك الخاص، حتى 200 حرف
dedupeOn "external_id" إعادة المظروف الموجود الذي يحمل قيمة externalId هذه بدلًا من إنشاء مظروف آخر
metadata كائن من سلاسل نصية حتى 500 حرف لكل قيمة؛ تُعاد مع المظروف وفي الـ webhooks

يحتاج كل مستلم إلى دور من أدوار الإصدار؛ ويحتاج كل دور غير CC إلى مستلم واحد بالضبط. تُعرض الأخطاء مجتمعةً، مع مؤشرات مثل /recipients/1/role أو /recipients/0/fields/start_date.

الاستجابات: 201 مع المظروف وترويسة Location؛ و200 مع المظروف الموجود وx-deduplicated: true عندما تتطابق dedupeOn؛ و200 مع ملخص التشغيل التجريبي لـ ?dry_run=true؛ و402 عندما تستنفد مساحة عمل Free مظاريفها المضمّنة؛ و403 plan-upgrade-required عندما يتجاوز عدد المشاهدين ما تسمح به الخطة أو لا تتضمن الخطة viewerDocumentAccess (الخطط والحدود). ويتحقق التشغيل التجريبي من حدود الخطة أيضًا.

كل حقل أُضيف بعد الإصدار الأول اختياري: الطلب الذي لا يتضمنها يتصرف تمامًا كما كان من قبل.

يحدّد القالب من يوقّع وبأي ترتيب. ويمكنك تغيير ذلك لمظروف واحد دون المساس بالقالب:

{
"template": "tpl_9fK2mQ7xLp",
"variables": { "client": { "name": "Jane Doe" } },
"recipients": [
{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev", "order": 2 },
{ "role": "company", "name": "Sam Lee", "email": "sam@bonafide.dev", "order": 1 },
{ "role": "witness", "name": "Kim Park", "email": "kim@acme.dev", "order": 1 }
],
"cc": [{ "name": "Legal", "email": "legal@acme.dev" }],
"viewers": [{ "name": "Alex Chen", "email": "alex@acme.dev", "notifyOnSignature": true }],
"reminders": { "enabled": true, "intervalHours": 48 },
"expiresAt": "2026-11-30T23:59:59Z"
}
  • الترتيب: recipients[].order هو الخطوة التي يوقّع فيها المستلم؛ والمستلمون الذين يحملون الرقم نفسه يوقّعون في الوقت نفسه. وفي غيابه، يُطبَّق order الخاص بالدور من القالب. الترتيبات أعداد صحيحة موجبة؛ ولا يمكن ترتيب أدوار CC؛ ويظل كل دور بحاجة إلى مستلمه (كي تحتفظ حقول القالب بموقِّعها)؛ ويجب أن يوقّع مستلم واحد على الأقل. ويسجّل الحدث envelope.created القيمة routingOverridden: true.
  • CC: يتلقى مستلمو CC الإضافيون رسالة المستند المكتمل ولا يوقّعون أبدًا. ويظهرون في recipients مع kind: "cc" والدور _cc.
  • التذكيرات: يُذكَّر من حان دوره كل intervalHours (الافتراضي: قيمة REMINDER_INTERVAL_HOURS في بيئة النشر، أي 72)، بحد أقصى ثلاث مرات؛ ولا يرسل enabled: false أي تذكير. تنطبق التذكيرات على التسليم عبر email.
  • مصادقة الموقِّع تكون لكل مستلم: verification تتجاوز طريقة الدور. تتوفر اليوم none (رابط التوقيع الفريد وحده، وهو الافتراضي للأدوار التي لا تحدد طريقة) وemail_otp (الرابط مع رمز يُرسل بالبريد الإلكتروني)؛ أما passkey وid_check فتُرفضان لأنهما غير متاحتين بعد. راجع التحقق من الموقِّع.
  • اللغة: locale على مستلم أو CC أو مشاهد (أو على المظروف، لكل من لا يملك قيمة خاصة به) تحدّد لغة صفحة التوقيع والرسائل الخاصة به، وهي واحدة من لغات التوقيع الخمسين. وفي غيابها تتبع صفحة التوقيع لغة المتصفح وتكون الرسائل بالإنجليزية.

توفّر شاشة الإرسال في لوحة التحكم الخيارات نفسها: تقديم الخطوات أو تأخيرها، وتحديد التوقيع في الوقت نفسه، وإضافة CC ومشاهدين، واختيار طريقة مصادقة كل موقِّع (رابط البريد الإلكتروني فقط أو رابط البريد الإلكتروني + رمز) ولغته، وتعيين تاريخ انتهاء الصلاحية وجدول التذكيرات.

  • email: يُرسَل إلى كل مستلم رابط إلى صفحة التوقيع المستضافة عندما يحين دوره. ويتلقى المستلمون الذين لم يوقّعوا تذكيرًا كل بضعة أيام (حتى ثلاث مرات)، ويُرسَل بريد إلكتروني إلى الجميع عند اكتمال المظروف.
  • embedded: لا بريد إلكتروني للموقِّعين. أصدِر جلسة توقيع عندما يكون الموقِّع داخل منتجك. ويظل المشاهدون يتلقون رابط الحالة الخاص بهم بالبريد الإلكتروني.
  • none: لا بريد إلكتروني إطلاقًا (بما في ذلك المشاهدون)؛ استخدمه عندما تسلّم الروابط بنفسك (الجلسات المستضافة).

يرسل POST /v1/envelopes/{id}/recipients/{recipient}/resend رابطًا جديدًا بالبريد الإلكتروني إلى المستلم الذي حان دوره (مرة واحدة في الدقيقة على الأكثر).

┌──────────── declined (a signer declined)
│
sent ─────┼──────────── voided (POST /v1/envelopes/{id}/void)
│
├──────────── expired (expiresAt passed)
│
└──────────── completed ──► seal: pending ──► sealed
status المعنى
rendering قيد التحضير
sent قيد التنفيذ: يوقّع المستلمون وفق ترتيب التوجيه
completed أنهى كل المستلمين. يبدأ الختم
declined رفض أحد المستلمين؛ وينتهي المظروف
voided ألغيته أنت ({ "reason": "…" })؛ وتتوقف جلسات التوقيع المفتوحة عن العمل
expired انقضى expiresAt قبل الإتمام

يتتبع seal حالة ملف PDF المختوم: not_started، أو pending (مكتمل، وقيد الختم)، أو sealed، أو failed. لا يعيق الختم الإتمام أبدًا: يكتمل المظروف أولًا ثم يُختم مباشرة بعد ذلك.

{
"id": "rcp_5Jw0pLs9Xe",
"role": "client",
"name": "Jane Doe",
"email": "jane@acme.dev",
"order": 1,
"status": "viewed",
"verification": "email_otp",
"completedAt": null
}

قيمة status للمستلم هي pending (لم يحن دوره بعد)، أو sent، أو viewed، أو completed، أو declined، وkind هو نوع الدور: signer أو approver أو form_filler أو cc. يتم التوجيه حسب order (ترتيب الدور، أو تجاوزه وقت الإرسال): يتصرف كل مستلمي أدنى ترتيب لم يكتمل بالتوازي، وتبدأ المجموعة التالية عندما ينتهون. ولا يعيق مستلمو CC التوجيه أبدًا.

المشاهد يتابع المظروف دون أن يوقّع: مدير، أو مساعد قانوني، أو مسؤول الحساب لدى العميل. المشاهدون ليسوا مستلمين. فليس لهم دور ولا دور في الترتيب، ولا يعيقون أي شيء ولا يُكملونه، ولا يظهرون أبدًا في قائمة الموقِّعين في الشهادة.

  • عند إرسال المظروف (أو عند إضافتهم لاحقًا باستخدام POST /v1/envelopes/{id}/viewers)، يتلقى كل مشاهد رسالة بريد إلكتروني بعلامتك التجارية تحتوي على رابط إلى صفحة حالة للقراءة فقط: عنوان المظروف، والمرسل، وكل خطوة مع أسماء مستلميها وأدوارهم وحالاتهم وطوابعهم الزمنية، بشكل مباشر أثناء التوقيع. ولا تُعرض عناوين البريد الإلكتروني للمستلمين.
  • يتلقى المشاهدون رسالة بريد إلكتروني مجددًا عند اكتمال المظروف أو رفضه أو إلغائه، وبعد كل توقيع إذا كانت notifyOnSignature تساوي true (معطّل افتراضيًا).
  • لا يظهر المستند على الصفحة إلا عند تعيين viewerDocumentAccess: true (خطة Team فما فوق): الأصل أثناء التنفيذ، وملف PDF المختوم بعد الختم. وإلا فلا يرى المشاهدون سوى الحالة.
  • يلغي DELETE /v1/envelopes/{id}/viewers/{viewer} وصول المشاهد: يتوقف كل رابط أُرسل إليه عن العمل فورًا.
  • الروابط عناوين URL شخصية تمنح صلاحية الوصول. ولا يُخزَّن من رمز كل رابط سوى تجزئة SHA-256. يعمل الرابط حتى تنتهي صلاحية المظروف (90 يومًا على الأكثر)، ولمدة 30 يومًا بعد انتهاء المظروف، ولا يعمل أبدًا بعد إلغاء وصول المشاهد.
  • تُسجَّل الإضافة والفتح (أول عرض للصفحة وللمستند) والإلغاء في مسار التدقيق بصفتها viewer.added وviewer.viewed وviewer.document_viewed وviewer.revoked، وبالتالي في الشهادة.

تعرضهم استجابات المظروف الواحد (الإنشاء، والجلب، والإلغاء):

{
"viewers": [
{
"id": "vwr_2Hc8sQ1nVt",
"name": "Alex Chen",
"email": "alex@acme.dev",
"notifyOnSignature": true,
"status": "active",
"invitedAt": "2026-10-13T13:58:04.512Z",
"firstViewedAt": "2026-10-13T14:05:41.090Z",
"lastViewedAt": "2026-10-13T15:12:09.337Z",
"revokedAt": null,
"createdAt": "2026-10-13T13:58:04.512Z"
}
],
"viewerDocumentAccess": false
}

يعتمد عدد المشاهدين لكل مظروف على الخطة (Free: 1، وPay-as-you-go: 2، وTeam: 5، وBusiness: 20، وPlatform: بلا حد)؛ ولا يُحتسب مستلمو CC. ويُحرِّر المشاهدون الملغى وصولهم أماكنهم.

ينزّل GET /v1/envelopes/{id}/document?version=… ملف PDF، مع تجزئة SHA-256 الخاصة به في x-document-sha256:

version الملف
original (الافتراضي) المستند المعروض كما أُرسل للتوقيع
sealed ملف PDF النهائي: القيم مدمجة في الصفحة، وشهادة الإتمام ملحقة، وطابع زمني للمستند. بعد envelope.sealed
certificate شهادة الإتمام وحدها

قيمة documentHash للمظروف هي تجزئة SHA-256 للأصل، وsealedDocumentHash هي تجزئة الملف المختوم؛ وهما ما يبحث عنه التحقق.

كل إجراء حدث في سلسلة تجزئة خاصة بكل مظروف: hash = SHA-256(prevHash ‖ canonical JSON of the event)، وأول prevHash هو 64 صفرًا. يعيد GET /v1/envelopes/{id}/events الأحداث ويتحقق من السلسلة:

{
"data": [
{
"id": "evt_…",
"envelope": "env_8Gm2kQ4rT1",
"seq": 1,
"type": "envelope.created",
"createdAt": "2026-10-13T13:58:04.512Z",
"recipient": null,
"actor": { "kind": "api_key", "id": "…", "name": null, "email": null },
"ip": "203.0.113.7",
"userAgent": null,
"data": { "template": "tpl_…", "templateVersion": 3, "documentHash": "9f2c…" },
"hash": "4b1d…",
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000"
}
],
"chain": { "valid": true, "brokenAt": null }
}

إلى جانب أنواع أحداث webhook، يتضمن المسار إدخالات خاصة بالتدقيق فقط مثل session.created وrecipient.verified وrecipient.reminded وأحداث المشاهدين (نوع الفاعل viewer عندما يفتح المشاهد صفحته).

لعرض الحالة مباشرة في واجهة مستخدم، يوفّر GET /v1/envelopes/{id}/events/stream تدفق أحداث مرسلة من الخادم (SSE): اسم الحدث في كل إطار هو type الخاص بالحدث ومعرّفه هو seq؛ أعِد الاتصال مع Last-Event-ID للاستئناف.

يُصفّي GET /v1/envelopes حسب status وseal وtemplate وq (نص حر يبحث في أسماء المستلمين وعناوين بريدهم الإلكتروني، وexternalId ومعرّف المظروف). وكأي قائمة، يُقسَّم إلى صفحات بمؤشر (cursor):

{ "data": [ … ], "hasMore": true, "nextCursor": "…" }

أعِد nextCursor في المعامل cursor؛ وقيمة limit من 1 إلى 100 (الافتراضي 20).