> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# تحديث حالة الجلسة: واجهة برمجة الموافقة والرفض

> موافقة على جلسات KYC وKYB أو رفضها أو نقلها إلى قيد المراجعة عبر Didit باستخدام PATCH /v3/session/{id}/update-status/. بدون حد أدنى شهري.



موجّه تحديث حالة الجلسة
        نسخ الموجّه إلى الحافظة



      
      

\<pre>

\`Manually approve, decline, or re-open a Didit verification session.

Endpoint:
PATCH https://verification.didit.me/v3/session/{session_id}/update-status/

Authentication:
Use the x-api-key header with your Didit API key (or a user-auth token). Privilege: write:sessions.

Path parameter:
\- session_id (UUID) — KYC or KYB; Didit resolves it against both session types.

Request body:
\- new_status (string, required) — One of "Approved", "Declined", "Resubmitted". Any other value is rejected.
\- comment (string, optional) — Free-text note saved on the audit trail (visible in the Console review log).
\- nodes_to_resubmit (array, required when new_status="Resubmitted") — Which feature steps the user must redo. Each entry: { "node_id": "feature_poa_1", "feature": "POA" }. KYB-only nodes "KYB_REGISTRY" and "KYB_KEY_PEOPLE" cannot be resubmitted directly (the parent recomputes from child KYCs).
\- send_email (boolean, optional, default false): if true, email the person. "Approved" and "Declined" send their decision email; "Resubmitted" sends a fresh hosted link with the reasons.
\- email_address (string, required when send_email=true).
\- email_language (string, optional, default "en") — ISO 639-1.
\- email_preview_token (string, optional): the preview_token from Preview Decision Email ("Approved", "Declined") or Preview Resubmission Email ("Resubmitted"). Only valid with send_email=true; without it the request returns 400 { "email_preview_token": ["A preview receipt is only valid when the email is sent."] }. The update then sends exactly the previewed email, or returns 409 before changing anything if the email or the session changed since the preview.

Optional preview step (all three statuses):
1\. Preview the email. Neither call changes the session or sends anything.
\- Approved or Declined: POST https://verification.didit.me/v3/session/{session_id}/decision-email-preview/ with { "new_status": "Approved", "email_language": "en" } (see /sessions-api/preview-decision-email).
\- Resubmitted: POST https://verification.didit.me/v3/session/{session_id}/resubmission-preview/ with { "nodes_to_resubmit": [...], "email_language": "en" } (see /sessions-api/preview-resubmission). email_address is optional there; without it the email goes to the person's own address.
2\. Check subject, html, recipient, will_be_sent and not_sent_reason in the response.
3\. Confirm here with the same new_status (and the same nodes_to_resubmit for Resubmitted), send_email=true, email_address=<recipient>, email_language=<the language you previewed>, email_preview_token=<preview_token>.
The receipt expires after 15 minutes.

Allowed transitions:
Current status must be one of: Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted. Otherwise the API returns 400 { "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: ..." }.
Setting "Approved" or "Declined" on a session that already has that status is a no-op: 200, nothing changes, and no webhook or email goes out. Setting "Resubmitted" on a session that is already Resubmitted returns 400 ["The new status is the same as the current status."].

curl example — approve after manual review:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Approved",
"comment": "Cleared after compliance review."
}'

curl example: approve and send the email you previewed:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Approved",
"send_email": true,
"email_address": "<recipient from the preview>",
"email_language": "en",
"email_preview_token": "<preview_token from the preview>"
}'

curl example — request resubmission of the proof-of-address step:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Resubmitted",
"nodes_to_resubmit": [{ "node_id": "feature_poa_1", "feature": "POA" }],
"comment": "Please upload a clearer proof of address",
"send_email": true,
"email_address": "user@example.com"
}'

Response: { "session_id": "<uuid>" } only. Fetch the refreshed session with GET /v3/session/{session_id}/decision/.

Side effects:
\- Fires a status.updated webhook (plus user.status.updated or business.status.updated alias).
\- Writes an entry to the Console review trail with the actor and your comment.
\- "Approved" or "Declined" with send_email=true emails the decision to email_address. Preview Decision Email tells you beforehand whether it will be sent (for example, not to the contact_details address of a session created without contact_details.send_notification_emails=true).
\- "Resubmitted" sends the user back to the steps in nodes_to_resubmit, resets the session expiration window, and (if send_email=true) emails the user a fresh link. What those steps returned before stays readable: the decision endpoint returns it with include=resubmissions (see Retrieve Session).

Failure modes:
\- 400: invalid new_status (only "Approved", "Declined" and "Resubmitted" are accepted), current status not allowed, nothing to resubmit, send_email=true without email_address, or email_preview_token without send_email=true. Field errors look like { "<field>": ["..."] }.
\- 401: the scoped API key has expired.
\- 403: { "detail": "..." } when credentials are missing or invalid, the caller lacks write:sessions (a scoped API key needs decisions write), or the session belongs to another application.
\- 404: { "detail": "Not found." } when no session with this session_id exists.
\- 409: { "detail": "This email preview changed or expired. Preview the message again before confirming." } when email_preview_token no longer matches the email or the session, or is older than 15 minutes. Nothing changed and no email was sent: preview again.
\- 429 - { "detail": "..." } when a resubmit that only targets backend-only features (AML, DATABASE_VALIDATION, IP_ANALYSIS) repeats within 30 seconds of the previous resubmit. Those features re-run automatically with no user interaction, so an immediate repeat cannot change the outcome; honor the Retry-After header instead of retrying in a loop (e.g. from a webhook handler).

Idempotency:
Repeating "Approved" or "Declined" returns 200 and changes nothing. Repeating "Resubmitted" returns 400.

Next step:
After updating, call GET /v3/session/{session_id}/decision/ to fetch the refreshed payload — see /sessions-api/retrieve-session.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.`

\</pre>



      
      

الصق في

## دعم KYC وKYBيعمل هذا endpoint بالطريقة نفسها مع جلسات **التحقق من المستخدم (KYC)** و**التحقق من الشركات (KYB)**. يحلّ Didit قيمة `session_id` ضمن كلا نوعَي الجلسات، والتحقق من انتقالات الحالة واحد في الحالتين، إذ تنطبق قائمة الحالات نفسها على النوعين.لا تتضمن الاستجابة سوى `session_id`.
اقرأ `session_kind` من [استرجاع الجلسة](https://docs.didit.me/ar/sessions-api/retrieve-session.md) عندما يحتاج منطقك اللاحق إلى التفريق بين النوعين.## الانتقالات المسموحةيمكنك نقل الجلسة إلى `Approved` أو `Declined` أو `Resubmitted`.
أي قيمة أخرى لـ `new_status`، بما فيها `In Review`، تعيد `400`.
يجب أن تكون الحالة الحالية للجلسة واحدة من `Approved` أو `Declined` أو `In Review` أو `Kyc Expired` أو `Abandoned` أو `Resubmitted`، وإلا أعادت الواجهة `400`.تعيين `Approved` أو `Declined` على جلسة لها هذه الحالة بالفعل لا يُحدِث أي تغيير: تعيد الواجهة `200` ولا تغيّر شيئًا، ولا تُطلق أي webhook ولا ترسل أي بريد إلكتروني.
تعيين `Resubmitted` على جلسة هي `Resubmitted` بالفعل يعيد `400` (`The new status is the same as the current status.`).تُنفَّذ إعادة التقديم التي تحتوي `nodes_to_resubmit` فيها على ميزات خلفية فقط (`AML` و`DATABASE_VALIDATION` و`IP_ANALYSIS`) تلقائيًا، وتعيد الجلسة إلى حالة حُسم فيها القرار دون أي تفاعل من المستخدم.
تكرار إعادة التقديم هذه خلال 30 ثانية يعيد `429 Too Many Requests` مع الترويسة `Retry-After`، لأن التكرار الفوري لا يمكن أن يعطي نتيجة مختلفة.
لا تُعِد التقديم تلقائيًا من معالج webhook كلما وصلتك حالة `In Review`، بل راجِع النتيجة أو غيّر البيانات الأساسية أولًا.## معاينة البريد الإلكتروني أولًاعند ضبط `send_email: true`، ترسل `Approved` و`Declined` إلى الشخص بريد القرار الخاص به، وترسل `Resubmitted` إليه رابطًا جديدًا مع الأسباب.
يمكنك الاطلاع على هذا البريد قبل أن تغيّر أي شيء:1) استدعِ [معاينة بريد القرار الإلكتروني](https://docs.didit.me/ar/sessions-api/preview-decision-email.md) للحالة `Approved` أو `Declined`، أو [معاينة بريد إعادة التقديم الإلكتروني](https://docs.didit.me/ar/sessions-api/preview-resubmission.md) للحالة `Resubmitted`.
2) تحقّق من `subject` و`html` المعروضين، و`recipient`، وقيمتي `will_be_sent` / `not_sent_reason`.
3) استدعِ هذه الواجهة بالقيمة `new_status` نفسها (وبالقيمة `nodes_to_resubmit` نفسها في حالة إعادة التقديم)، مع `send_email: true`، و`email_address` مضبوطًا على `recipient`، و`email_language` بالقيمة التي عاينتها، و`email_preview_token` مضبوطًا على `preview_token`.لا تغيّر أيٌّ من المعاينتين الجلسة ولا ترسل شيئًا.
ثم يرسل التحديث البريد الذي عاينته تمامًا.
تنتهي صلاحية الإيصال بعد 15 دقيقة.
إذا تغيّر المستلم أو اللغة أو حالة الجلسة أو المُرسِل أو البريد منذ المعاينة، يعيد التحديث `409` قبل أن يتغيّر أي شيء؛ أعِد المعاينة وأكّد باستخدام الإيصال الجديد.
إرسال `email_preview_token` دون `send_email: true` يعيد `400`.
خطوة المعاينة اختيارية: يمكن للتكاملات القائمة أن تواصل استدعاء هذا endpoint دونها.## أمثلة> [tab] الموافقة على جلسة التحقق من المستخدم (KYC)
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Cleared after manual review by compliance team"
>   }'
> ```> [tab] رفض جلسة التحقق من الشركات (KYB)
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/bs-01HJX1.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Declined",
>     "comment": "Sanctioned subsidiary detected in ownership chain"
>   }'
> ```> [tab] طلب إعادة التقديم
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Resubmitted",
>     "nodes_to_resubmit": [
>       { "node_id": "feature_poa_1", "feature": "POA" }
>     ],
>     "comment": "Please upload a clearer proof of address",
>     "send_email": true,
>     "email_address": "user@example.com"
>   }'
> ```> [tab] الموافقة وإرسال البريد الذي تمت معاينته
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "send_email": true,
>     "email_address": "user@example.com",
>     "email_language": "en",
>     "email_preview_token": "PREVIEW_TOKEN_FROM_THE_PREVIEW"
>   }'
> ```## الإذنيتطلب الإذن `write:sessions`. ويغطي الإذن نفسه النوعين معًا.## ذو صلة- [حالات التحقق](https://docs.didit.me/ar/integration/verification-statuses.md) - مرجع آلة الحالات.
- [استرجاع الجلسة](https://docs.didit.me/ar/sessions-api/retrieve-session.md) - جلب القرار بعد التحديث.
- [نظرة عامة على الجلسات](https://docs.didit.me/ar/sessions-api/overview.md) - التفريق بين أنواع الجلسات.
- [معاينة بريد القرار الإلكتروني](https://docs.didit.me/ar/sessions-api/preview-decision-email.md): اطّلع على بريد الموافقة أو الرفض قبل إرساله.
- [معاينة بريد إعادة التقديم الإلكتروني](https://docs.didit.me/ar/sessions-api/preview-resubmission.md): اطّلع على بريد إعادة التقديم قبل إرساله.


## OpenAPI

````yaml ar/openapi-25.json PATCH /v3/session/{sessionId}/update-status/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API التحقق من الهوية. قم بالمصادقة باستخدام الرأس x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/session/{sessionId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: الموافقة على جلسة التحقق أو رفضها أو طلب إعادة إرسالها
      description: >-
        تجاوز القرار النهائي لجلسة تحقق KYC أو KYB يدويًا. اضبط `new_status` على
        `Approved` أو `Declined` لتسجيل قرار يدوي، أو على `Resubmitted` لمسح
        خطوات تحقق معينة والسماح للمستخدم بإعادة إجرائها عبر رابط التحقق نفسه.
        يقبل الـ endpoint كلاً من معرفات جلسات المستخدمين (KYC) والشركات (KYB).


        استدعه بمجرد وصول الجلسة إلى حالة قابلة للمراجعة: يجب أن تكون الحالة
        الحالية `Approved` أو `Declined` أو `In Review` أو `Kyc Expired` أو
        `Abandoned` أو `Resubmitted`. الجلسات التي لا تزال في حالة `Not Started`
        أو `In Progress` أو `Awaiting User`، أو التي انتهت كـ `Expired`، تُرجع
        `400`. يحتاج مفتاح API الخاص بك إلى إذن `write:sessions` (يحتاج مفتاح
        API محدود النطاق إلى حق الوصول للكتابة على القرارات). يعمل فحص الحالة
        المؤهلة قبل التحقق من صحة نص الطلب، لذا تُرجع الجلسة غير المؤهلة خطأ
        `Wrong Current Status` حتى عندما يكون payload غير صالح أيضًا.


        بالنسبة لـ `Resubmitted`، مرّر `nodes_to_resubmit` لاختيار خطوات سير
        العمل التي يجب على المستخدم إعادتها، أو احذفه للتحديد التلقائي لمحاولات
        الميزات الحالية الموجودة في حالة قابلة لإعادة الإرسال (`Declined`، `In
        Review`، `Not Finished`، `Expired`). لا يتم تحديد الميزات التي لم تتم
        محاولتها من قبل تلقائيًا: اذكرها صراحةً في `nodes_to_resubmit`، وإلا فإن
        الطلب يُرجع `400` عند عدم وجود محاولة مسجلة تتطلب إعادة الإرسال. تنتقل
        النتائج السابقة للخطوات المحددة إلى سجل إعادة الإرسال (يتم إرجاعه بواسطة
        Get Decision مع `include=resubmissions`)، ويُعاد ترتيب الخطوات لتطابق
        مخطط سير العمل، وتُعاد نافذة انتهاء صلاحية الجلسة للبدء من جديد، ويصبح
        رابط التحقق الأصلي قابلاً للاستخدام مرة أخرى. خطوات الواجهة الخلفية فقط
        (`AML`، `DATABASE_VALIDATION`، `IP_ANALYSIS`) في بداية القائمة تعمل
        فورًا دون تفاعل المستخدم؛ وإذا كانت كل خطوة مُعاد إرسالها مقتصرة على
        الواجهة الخلفية فقط، تُحسم الجلسة مجددًا ضمن نفس الطلب. لا يمكن إعادة
        إرسال `KYB_REGISTRY` و`KYB_KEY_PEOPLE` مباشرة: أعد إرسال جلسات KYC
        الفرعية ذات الصلة بدلاً من ذلك ويُعاد احتساب جلسة الشركة الأم تلقائيًا.


        كل استدعاء يغيّر الحالة يُطلق حدث [webhook](/ar/integration/webhooks)
        `status.updated` بمجرد تطبيق التغيير ويُلحق إدخال نشاط (مع إسناد الفاعل
        والتعليق الخاص بك `comment`) إلى `reviews` الخاصة بالجلسة، ويكون ظاهرًا
        في [Get Decision](#get-/v3/session/-sessionId-/decision/) وفي الجدول
        الزمني للنشاط في لوحة التحكم. يتم أيضًا تحديث إجماليات الملف التعريفي
        للمستخدم المرتبطة بـ `vendor_data` الخاصة بالجلسة. يؤدي الرفض إلى تعطيل
        مراقبة AML المستمرة للجلسة؛ وتؤدي إعادة الموافقة إلى إعادة تفعيلها (من
        `Resubmitted` أو `Declined` أو `Kyc Expired`) عندما تكون المراقبة
        مُفعّلة في سير العمل. تؤدي الموافقة على جلسة KYC فرعية أو رفضها والتابعة
        لفحص الأشخاص الرئيسيين في KYB إلى إعادة احتساب حالة جلسة الشركة الأم.
        اضبط `send_email: true` (مع `email_address`) لإشعار المستخدم: إشعار
        بالحالة لـ `Approved`/`Declined`، أو بريد إلكتروني لإعادة الإرسال يحتوي
        على رابط التحقق وأسباب كل خطوة لـ `Resubmitted`. للتحقق من البريد
        الإلكتروني أولاً، عاينه باستخدام [Preview Decision
        Email](/ar/sessions-api/preview-decision-email) (`Approved`، `Declined`)
        أو [Preview Resubmission Email](/ar/sessions-api/preview-resubmission)
        (`Resubmitted`) ومرّر `preview_token` الخاص به كـ `email_preview_token`:
        يُرسل التحديث بعد ذلك البريد الإلكتروني الذي تمت معاينته تمامًا، أو
        يُرجع `409` قبل تغيير أي شيء عندما يتغير البريد الإلكتروني أو الجلسة منذ
        المعاينة أو إذا كان الإيصال أقدم من 15 دقيقة.


        تكرار `Approved` أو `Declined` على جلسة تحتوي بالفعل على تلك الحالة لا
        يغير شيئًا ويُرجع `200`: لا webhook، ولا إدخال نشاط، ولا بريد إلكتروني.
        تكرار `Resubmitted` يُرجع `400` (`The new status is the same as the
        current status.`). تُرجع بيانات الاعتماد المفقودة أو غير الصالحة
        والأذونات المفقودة `403`؛ ويُرجع مفتاح API محدود النطاق منتهي الصلاحية
        `401`.
      operationId: patch_v3_session_update_status
      parameters:
        - in: path
          name: sessionId
          required: true
          description: >-
            معرّف UUID لجلسة التحقق المطلوب تحديثها. يقبل معرّفات جلسات
            المستخدمين (KYC) والشركات (KYB) — يطابق الخادم المعرّف عبر كلا نوعي
            الجلسات.
          schema:
            type: string
            format: uuid
            example: 11111111-2222-3333-4444-555555555555
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - new_status
              properties:
                new_status:
                  type: string
                  description: >-
                    الحالة المستهدفة. تسجّل `Approved` و`Declined` قراراً يدوياً
                    نهائياً (يمكن لكل منهما أيضاً نقض الآخر). تمسح `Resubmitted`
                    الخطوات المحددة وتُعيد الجلسة إلى المستخدم. تُرجع أي قيمة
                    أخرى الرمز `400`.
                  enum:
                    - Approved
                    - Declined
                    - Resubmitted
                  example: Approved
                comment:
                  type: string
                  description: >-
                    سبب التغيير بنص حر، يُخزَّن في مسار مراجعة الجلسة ويُعاد في
                    مصفوفة `reviews` ضمن [Get
                    Decision](#get-/v3/session/-sessionId-/decision/). على سبيل
                    المثال `Duplicated user`.
                  example: All checks passed manual review
                nodes_to_resubmit:
                  type: array
                  description: >-
                    خطوات سير العمل التي يجب على المستخدم إعادتها. يتم تطبيقها
                    فقط عندما تكون قيمة `new_status` هي `Resubmitted`. بالنسبة
                    للحالتين `Approved`/`Declined`، يظل التحقق من صحة المدخلات
                    وفقاً للمخطط سارياً (أي قيمة غير صالحة لـ `feature` تُرجع
                    `400`) ولكن المدخلات الصالحة وفقاً للمخطط يتم تجاهلها
                    دلالياً. في حال حذفها، يحدد الخادم تلقائياً المحاولات
                    الحالية لـ OCR وكشف الحيوية ومطابقة الوجه وPOA ورقم الهاتف
                    والبريد الإلكتروني وفحص AML والتحقق من قواعد البيانات
                    والاستبيانات التي تكون حالتها `Declined` أو `In Review` أو
                    `Not Finished` أو `Expired` (لا يتم تحديد محاولات NFC وتحليل
                    IP وتقدير العمر والبحث بالوجه ومستندات KYB تلقائياً على
                    الإطلاق؛ ويتم تحديد محاولات الوجه بخلاف مطابقة الوجه كـ
                    `LIVENESS`) — الميزات التي لم يحاول المستخدم إجراؤها مطلقاً
                    (لا توجد محاولة مسجلة) لن يتم تحديدها، وبالتالي فإن الجلسة
                    التي تحتوي على صفر من المحاولات تُرجع `400` ("No features
                    found that need resubmission") على الرغم من عدم قبول أي شيء؛
                    مرّر `nodes_to_resubmit` صراحة في هذه الحالة. يتم تنفيذ
                    الخطوات وفقاً لترتيب مخطط سير العمل بغض النظر عن الترتيب
                    الذي ترسله بها. يتم رفض `KYB_REGISTRY` و`KYB_KEY_PEOPLE`
                    والاسم البديل `KYB` بالرمز `400` — تُعاد حوسبة عمليات التحقق
                    الرئيسية تلك من جلسات KYC الفرعية الخاصة بها.
                  items:
                    type: object
                    required:
                      - node_id
                      - feature
                    properties:
                      node_id:
                        type: string
                        description: >-
                          معرّف العقدة كما يظهر في تعريف سير عمل الجلسة (على
                          سبيل المثال `feature_ocr`، `feature_liveness`).
                        example: feature_ocr
                      feature:
                        type: string
                        description: >-
                          نوع الميزة للعقدة. يتم توحيد الأسماء المستعارة
                          `ID_VERIFICATION` و`POA` و`PHONE` و`EMAIL` من جانب
                          الخادم إلى `OCR` و`PROOF_OF_ADDRESS`
                          و`PHONE_VERIFICATION` و`EMAIL_VERIFICATION`. تجتاز
                          `KYB_REGISTRY` و`KYB_KEY_PEOPLE` و`KYB` التحقق من صحة
                          المخطط ولكن يتم رفضها دائمًا مع قاعدة العمل `400`
                          الموضحة في الأمثلة.
                        enum:
                          - OCR
                          - OCR_BACK
                          - NFC
                          - AML
                          - FACE
                          - LIVENESS
                          - FACE_MATCH
                          - IP_ANALYSIS
                          - AGE_ESTIMATION
                          - PROOF_OF_ADDRESS
                          - PHONE_VERIFICATION
                          - EMAIL_VERIFICATION
                          - FACE_SEARCH
                          - DATABASE_VALIDATION
                          - QUESTIONNAIRE
                          - DOCUMENT_AI
                          - KYB_DOCUMENTS
                          - ID_VERIFICATION
                          - POA
                          - PHONE
                          - EMAIL
                          - KYB_REGISTRY
                          - KYB_KEY_PEOPLE
                          - KYB
                          - GEOLOCATION
                        example: OCR
                send_email:
                  type: boolean
                  description: >-
                    ما إذا كان سيتم إرسال بريد إلكتروني إلى المستخدم بشأن
                    التغيير. يتطلب `email_address`. بالنسبة إلى
                    `Approved`/`Declined`، يتلقى المستخدم إشعاراً بالحالة؛
                    وبالنسبة إلى `Resubmitted`، يتضمن البريد الإلكتروني رابط
                    التحقق وأسباب إعادة الإرسال لكل خطوة.
                  default: false
                  example: false
                email_address:
                  type: string
                  format: email
                  description: >-
                    المستلم لبريد الإشعار الإلكتروني. **مطلوب عندما يكون
                    `send_email` بقيمة `true`** — يؤدي حذفه إلى إرجاع `400`.
                  example: user@example.com
                email_language:
                  type: string
                  description: >-
                    لغة البريد الإلكتروني للإشعار. يقبل أي سلسلة نصية على مستوى
                    المخطط؛ تعود الرموز غير المدعومة تلقائياً وبصمت إلى اللغة
                    الإنجليزية (`en`).
                  default: en
                  example: en
                email_preview_token:
                  type: string
                  writeOnly: true
                  minLength: 1
                  maxLength: 512
                  description: >-
                    إيصال اختياري من [معاينة بريد القرار
                    الإلكتروني](/ar/sessions-api/preview-decision-email) (لـ
                    `Approved` و `Declined`) أو [معاينة بريد إعادة التقديم
                    الإلكتروني](/ar/sessions-api/preview-resubmission) (لـ
                    `Resubmitted`): رمز `preview_token` الخاص به. صالح فقط مع
                    `send_email: true`؛ بدونه يُرجع الطلب `400`. يجب أن يظل
                    المستلم واللغة وحالة الجلسة والمرسل والبريد الإلكتروني
                    (والخطوات المحددة، في حالة إعادة التقديم) متطابقة مع
                    المعاينة، وتنتهي صلاحية الإيصال بعد 15 دقيقة. وإلا فإن الطلب
                    يُرجع `409` قبل تغيير الجلسة أو إرسال بريد إلكتروني. يجوز
                    لعمليات التكامل الحالية إغفال هذا الحقل.
            examples:
              Approve Session:
                summary: الموافقة على جلسة بعد مراجعة يدوية
                value:
                  new_status: Approved
                  comment: All checks passed manual review
              Decline Session:
                summary: رفض جلسة
                value:
                  new_status: Declined
                  comment: Suspected fraud
              Resubmit Specific Steps:
                summary: طلب إعادة تقديم الخطوات المحددة، مع إرسال بريد إلكتروني
                value:
                  new_status: Resubmitted
                  nodes_to_resubmit:
                    - node_id: feature_ocr
                      feature: OCR
                    - node_id: feature_liveness
                      feature: LIVENESS
                  send_email: true
                  email_address: user@example.com
                  email_language: en
              Resubmit Auto-select:
                summary: طلب إعادة التقديم (تحديد تلقائي للخطوات غير المقبولة)
                value:
                  new_status: Resubmitted
              Approve With Previewed Email:
                summary: >-
                  الموافقة على البريد الإلكتروني الذي تم إرجاعه بواسطة Preview
                  Decision Email وإرساله
                value:
                  new_status: Approved
                  send_email: true
                  email_address: person@example.com
                  email_language: en
                  email_preview_token: >-
                    eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000
      responses:
        '200':
          description: >-
            تم تحديث الحالة. تحتوي الاستجابة فقط على `session_id`؛ يمكنك جلب
            الجلسة المحدثة عبر [Get
            Decision](#get-/v3/session/-sessionId-/decision/). يتم تشغيل webhook
            الخاص بـ `status.updated` بمجرد تطبيق التغيير. يؤدي تكرار `Approved`
            أو `Declined` إلى إرجاع نفس نص الاستجابة دون تغيير أي شيء.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                    description: معرّف UUID للجلسة المحدّثة.
              examples:
                Updated:
                  summary: >-
                    يتم إرجاعها لحالات المقبولة والمرفوضة والمعاد تقديمها على حد
                    سواء
                  value:
                    session_id: 3472fb7c-8f7c-4d1a-9cf4-cf3d74ce1a60
        '400':
          description: >-
            خطأ في التحقق. تصل أخطاء الحقول على شكل `{"<field>": ["<message>"]}`
            (تستخدم بعض حالات رفض قواعد العمل قيمة نصية بدلاً من ذلك:
            `{"nodes_to_resubmit": "<message>"}`)، وأخطاء تبديل الحالات على شكل
            `{"detail": "<message>"}`، وخطأ الحالة المتطابقة كمصفوفة JSON مجردة.
          content:
            application/json:
              examples:
                Wrong Current Status:
                  summary: الجلسة ليست في حالة قابلة للتحديث
                  value:
                    detail: >-
                      Only sessions with status Approved, Declined, In Review,
                      Kyc Expired, Abandoned, Resubmitted can be updated.
                      Current status: In Progress
                Invalid Status Value:
                  summary: >-
                    حقل new_status يمثل حالة جلسة حقيقية ولكنه ليس إحدى الحالات
                    Approved/Declined/Resubmitted
                  value:
                    new_status:
                      - >-
                        You can only update the status to 'Approved',
                        'Declined', or 'Resubmitted'.
                Missing new_status:
                  summary: تم إغفال حقل مطلوب
                  value:
                    new_status:
                      - This field is required.
                Same Status:
                  summary: طُلبت إعادة الإرسال في جلسة تمت إعادة إرسالها بالفعل
                  value:
                    - The new status is the same as the current status.
                Email Address Required:
                  summary: send_email بقيمة true بدون email_address
                  value:
                    email_address:
                      - Email address is required when send_email is true.
                Non-resubmittable Feature:
                  summary: تستهدف إعادة الإرسال فحص KYB الأب
                  value:
                    nodes_to_resubmit: >-
                      The following features cannot be resubmitted directly:
                      KYB_REGISTRY. Resubmit the relevant child KYC sessions
                      instead; the parent will recompute automatically.
                Nothing To Resubmit:
                  summary: لم يعثر الاختيار التلقائي على أي ميزات غير مقبولة
                  value:
                    nodes_to_resubmit: >-
                      No features found that need resubmission. All features are
                      already approved.
                Invalid Feature Choice:
                  summary: ميزة غير معروفة في nodes_to_resubmit
                  value:
                    nodes_to_resubmit:
                      - feature:
                          - >-
                            "BOGUS" is not a valid choice. Valid choices are:
                            OCR, OCR_BACK, NFC, AML, FACE, LIVENESS, FACE_MATCH,
                            IP_ANALYSIS, AGE_ESTIMATION, PROOF_OF_ADDRESS,
                            PHONE_VERIFICATION, EMAIL_VERIFICATION, FACE_SEARCH,
                            DATABASE_VALIDATION, QUESTIONNAIRE, KYB_REGISTRY,
                            KYB_DOCUMENTS, KYB_KEY_PEOPLE, ID_VERIFICATION, POA,
                            PHONE, EMAIL, KYB
                Invalid Status Value (not a status at all):
                  summary: حقل new_status ليس قيمة صالحة من قيم StatusChoices
                  value:
                    new_status:
                      - '"Bogus" is not a valid choice.'
                Preview Receipt Without Email:
                  summary: 'تم إرسال email_preview_token بدون send_email: true'
                  value:
                    email_preview_token:
                      - A preview receipt is only valid when the email is sent.
        '401':
          description: انتهت صلاحية مفتاح API محدد النطاق.
          content:
            application/json:
              examples:
                Expired API Key:
                  summary: مفتاح API محدد النطاق تجاوز تاريخ انتهاء صلاحيته
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            بيانات اعتماد مفقودة أو أذونات غير كافية، أو `session_id` ينتمي إلى
            تطبيق آخر.
          content:
            application/json:
              examples:
                Invalid Credentials:
                  summary: x-api-key مفقود أو غير صالح
                  value:
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                Missing Privilege:
                  summary: يفتقر مفتاح API إلى write:sessions
                  value:
                    detail: You do not have permission to perform this action.
        '404':
          description: >-
            لا توجد جلسة KYC أو KYB بمعرّف `session_id` هذا (الجلسات المحذوفة
            تُرجع أيضاً `404`).
          content:
            application/json:
              examples:
                Not Found:
                  summary: session_id غير معروف
                  value:
                    detail: Not found.
        '409':
          description: >-
            تغيرت معاينة البريد الإلكتروني أو انتهت صلاحيتها. أنشئ معاينة جديدة
            قبل التأكيد؛ لا تحدث أي تغييرات في الجلسة أو تسليم البريد
            الإلكتروني.
          content:
            application/json:
              examples:
                Preview Changed:
                  summary: لم يعد الإيصال متطابقاً، أو مر عليه أكثر من 15 دقيقة
                  value:
                    detail: >-
                      This email preview changed or expired. Preview the message
                      again before confirming.
        '429':
          description: >-
            تم تكرار إعادة إرسال تستهدف فقط الميزات المقتصرة على الواجهة الخلفية
            (AML، DATABASE_VALIDATION، IP_ANALYSIS) خلال فترة التهدئة البالغة 30
            ثانية؛ لن يؤدي التكرار الفوري إلى تغيير النتيجة. تراجع وأعد المحاولة
            بعد الفاصل الزمني الموضح في `Retry-After`.
          content:
            application/json:
              examples:
                Backend-only resubmit throttled:
                  value:
                    detail: >-
                      This session was already resubmitted for backend-only
                      features within the last 30 seconds; repeating it cannot
                      change the outcome. Wait before resubmitting again.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X PATCH \
              https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "Approved",
                "comment": "All checks passed manual review"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.update_status(
                "11111111-2222-3333-4444-555555555555",
                new_status="Approved",
                comment="All checks passed manual review",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: >-
            import Didit from "@didit-protocol/sdk-node";


            // Reads DIDIT_API_KEY.

            const didit = new Didit();


            const result = await
            didit.sessions.updateStatus("11111111-2222-3333-4444-555555555555",
            {
              new_status: "Approved",
              comment: "All checks passed manual review",
            });

            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"All checks passed manual review\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import me.didit.Didit;

            import me.didit.types.SessionsUpdateStatusParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().updateStatus("11111111-2222-3333-4444-555555555555",
            SessionsUpdateStatusParams.builder()
                    .newStatus(SessionsUpdateStatusParams.NewStatus.of("Approved"))
                    .comment("All checks passed manual review")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: >-
            <?php


            require 'vendor/autoload.php';


            use Didit\DiditClient;


            // Reads DIDIT_API_KEY.

            $didit = new DiditClient();


            $result =
            $didit->sessions->updateStatus('11111111-2222-3333-4444-555555555555',
            [
                'new_status' => 'Approved',
                'comment' => 'All checks passed manual review',
            ]);

            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.sessions.update_status(
              "11111111-2222-3333-4444-555555555555",
              new_status: "Approved",
              comment: "All checks passed manual review"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await
            client.Sessions.UpdateStatusAsync("11111111-2222-3333-4444-555555555555",
            new SessionsUpdateStatusParams

            {
                NewStatus = "Approved",
                Comment = "All checks passed manual review",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        مفتاح API الخاص بتطبيقك، من Developers -> API keys في Business Console.
        يمتلك المفتاح الأساسي وصولاً كاملاً. يمكن تحديد نطاق المفتاح المسمى: لا
        شيء، أو قراءة، أو كتابة لكل مورد، ومحدوداً ببعض مسارات العمل أو بالجلسات
        المقبولة، وبقائمة من عناوين IP، وبتاريخ انتهاء الصلاحية. يشير 401 إلى أن
        المفتاح غير صحيح أو ملغى أو منتهي الصلاحية؛ ويشير 403 إلى أنه لم يتم
        إرسال أي مفتاح، أو أن المفتاح ليس لديه حق الوصول إلى هذا المورد أو
        الإجراء، أو أن الطلب جاء من عنوان خارج قائمة عناوين IP الخاصة به؛ ويشير
        404 في مسار جلسة إلى أن الجلسة خارج مسارات العمل أو الحالات الخاصة
        بالمفتاح. يتلقى المفتاح الذي لا يمتلك حق الوصول إلى الوسائط عناوين URL
        للصور ومقاطع الفيديو وملفات PDF كـ null، ويتلقى المفتاح الذي لا يمتلك
        إذن كتابة للجلسات روابط الجلسة وtoken كـ null. راجع
        https://docs.didit.me/console/api-keys.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.