> ## 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.

# واجهة برمجة البحث بالوجه: مطابقة 1:N وحلقات الاحتيال

> POST /v3/face-search/ للبحث بالوجه 1:N بين المستخدمين المتحقق منهم في Didit. اكتشف الحسابات المكررة وحلقات الاحتيال. استدلال خلال 2s، دفع لكل استدعاء، بلا عقود.



## OpenAPI

````yaml ar/openapi-25.json POST /v3/face-search/
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/face-search/:
    post:
      tags:
        - Standalone APIs
      summary: البحث بالوجه
      description: >-
        ابحث عن صورة وجه (1:N) مقابل فهرس البحث بالوجه الخاص بتطبيقك — الوجوه
        المُسجَّلة من جلسات التحقق، واستدعاءات API المستقلة المحفوظة، وعمليات
        تحميل صور وجوه الملفات الشخصية للمستخدمين مباشرة، وقوائم الحظر/السماح
        الخاصة بك — واحصل على مطابقات مرتبة حسب التشابه بالإضافة إلى تحذيرات
        قائمة الحظر والتكرار.


        **طريقة العمل.** يتم تضمين أكبر وجه تم اكتشافه في `user_image` والبحث
        عنه في الفهرس، ضمن نطاق تطبيقك. يتم إرجاع ما يصل إلى **5 تطابقات**
        تتجاوز الحد الأدنى للتشابه في `matches`، ويحتوي كل منها على
        `similarity_percentage`، والجلسة الأصلية (`session_id` و`session_number`
        و`status` و`vendor_data`)، و`user_details` المستخرجة أثناء التحقق من
        المستندات لتلك الجلسة، وعلامتي `is_blocklisted` / `is_allowlisted`،
        ومميز `source` (`session` أو `imported` أو `list_entry`).


        - يرتب `search_type=most_similar` (الافتراضي) كل وجه مُسجَّل حسب التشابه
        — استخدمه لإزالة التكرار والتحقيق في شبكات الاحتيال.

        - يقصر `search_type=blocklisted_or_approved` المرشحين على الوجوه المدرجة
        في قائمة الحظر، والوجوه المدرجة في قائمة السماح، والوجوه من الجلسات
        المقبولة، ووجوه الملفات الشخصية للمستخدمين المستوردة، مع ترتيب الإدخالات
        المدرجة في قائمة الحظر أولاً — استخدمه عندما يكون الهدف الأساسي هو الفحص
        مقابل قائمة الحظر.


        تكون `status` بقيمة `Declined` فقط عند انطلاق تحذير `FACE_IN_BLOCKLIST`
        أو `POSSIBLE_FACE_IN_BLOCKLIST`؛ بينما لا تؤدي `DUPLICATED_FACE` /
        `POSSIBLE_DUPLICATED_FACE` (`information`) و`MULTIPLE_FACES_DETECTED`
        (`warning`) إلى الرفض مطلقاً. على عكس كشف الحيوية السلبي، **لا** يستبعد
        هذا الـ endpoint الجلسات السابقة التي تحتوي على `vendor_data` نفسها من
        المطابقة. يتم أيضاً تشغيل تحليل كشف الحيوية السلبي داخلياً وتخزينه مع
        الجلسة المحفوظة، لكن نتيجته ليست جزءاً من هذه الاستجابة.


        **الفوترة.** تستهلك كل استجابة `200` رصيد API واحداً للبحث بالوجه (يُدفع
        من رصيد خطتك أو رصيد الشحن). يؤدي عدم كفاية الرصيد إلى إرجاع `403` قبل
        معالجة أي صورة.


        **حفظ الجلسة وتسجيل الوجه (`save_api_request`، القيمة الافتراضية
        `true`).** عندما تكون القيمة `true`، يتم حفظ الاستدعاء كجلسة من نوع API‏
        (Business Console، و`GET /v3/session/{sessionId}/decision/` عبر
        `request_id` المُرجع، وwebhook الخاص بـ `status.updated`) ويتم تسجيل
        الوجه الذي تم البحث عنه في فهرس البحث بالوجه الخاص بك. يتم استبعاد
        الوجوه المُسجَّلة بواسطة استدعاءات البحث بالوجه من نتائج البحث بالوجه
        المستقبلية، بحيث لا تتطابق عمليات البحث المتكررة مع بعضها البعض مطلقاً.
        عندما تكون القيمة `false`، يكون الاستدعاء لمرة واحدة: لا يتم تخزين أي
        شيء، ولا يتم تسجيل الوجه، وتكون قيم `match_image_url` مسارات تخزين
        داخلية وليست عناوين URL قابلة للتنزيل.


        **البيئة التجريبية.** تتخطى مفاتيح API الخاصة بالبيئة التجريبية كل
        المعالجة والفوترة: بعد التحقق من صحة الطلب (المدخلات غير الصالحة لا تزال
        تُرجع `400`)، يُرجع الـ endpoint نموذج payload وهمياً ثابتاً بحالة
        `Approved`، ولا يتم حفظ أي جلسة، ولا يتم استهلاك أي رصيد.


        **المصادقة.** أرسل مفتاح API الخاص بتطبيقك في الرأس `x-api-key`. تُرجع
        بيانات الاعتماد المفقودة أو غير الصالحة `403`‏ (`{"detail": "You do not
        have permission to perform this action."}`) — لا يُرجع هذا الـ API الرمز
        `401` مطلقاً.


        **حد المعدل.** ميزانية كتابة مشتركة تبلغ 300 طلب/دقيقة لكل مفتاح API عبر
        جميع endpoints الخاصة بـ POST/PATCH/DELETE؛ يؤدي تجاوزها إلى إرجاع
        `429`.
      operationId: post_v3face-search
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - user_image
              properties:
                user_image:
                  type: string
                  format: binary
                  description: >-
                    صورة وجه أمامية للبحث بها. الامتدادات المسموح بها: `tiff`،
                    `jpg`، `jpeg`، `png`، `webp`. الحد الأقصى لحجم الرفع: **5
                    MB** (يتم رفض الملفات الأكبر حجماً بالرمز `400`). يتم ضغط
                    الصور تلقائياً إلى ~0.5 MB قبل المعالجة، لذا فإن دقة الصور
                    العالية جداً لا تحسّن دقة النتائج. يجب أن تحتوي الصورة على
                    وجه واحد قابل للاكتشاف على الأقل — وإلا فسيُرجع endpoint
                    الرمز `400`. عند وجود عدة وجوه، يتم البحث عن الوجه الأكبر
                    ويُضاف تحذير `MULTIPLE_FACES_DETECTED`.
                search_type:
                  type: string
                  default: most_similar
                  enum:
                    - most_similar
                    - blocklisted_or_approved
                  description: >-
                    سياسة البحث. يقوم `most_similar` (الافتراضي) بترتيب كل وجه
                    مسجل في تطبيقك حسب درجة التشابه. بينما يقصر
                    `blocklisted_or_approved` المرشحين على الوجوه المدرجة في
                    قائمة الحظر، والوجوه المدرجة في القائمة المسموح بها، والوجوه
                    من الجلسات المقبولة، والوجوه المستوردة من الملفات التعريفية
                    للمستخدمين — مع ترتيب الإدخالات المدرجة في قائمة الحظر
                    أولاً.
                  example: most_similar
                rotate_image:
                  type: boolean
                  default: false
                  description: >-
                    عندما تكون `true`، تجرب الخدمة تدوير الإدخال بزيادات قدرها
                    90 درجة وتستخدم الاتجاه الذي يحقق أفضل كشف للوجه. مفيد عند
                    فقدان اتجاه EXIF. يضيف تأخيراً في الاستجابة.
                  example: false
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    عندما تكون `true` (الافتراضي)، يتم حفظ الاستدعاء كجلسة من
                    نوع API، وإرسال webhook من نوع `status.updated`، وتوقيع قيم
                    `match_image_url` مسبقاً، وتسجيل الوجه الذي تم البحث عنه في
                    فهرس البحث بالوجه الخاص بك (تُستثنى عمليات تسجيل البحث
                    بالوجه من عمليات البحث المستقبلية). عندما تكون `false`، يكون
                    البحث لمرة واحدة فقط — لا يتم تخزين أي جلسة ولا يتم تسجيل
                    الوجه.
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    معرّف مبهم اختياري (معرّف المستخدم لديك، البريد الإلكتروني،
                    UUID...) يتم تخزينه في الجلسة المحفوظة وإعادته. لا يستبعد
                    وجوه نفس المستخدم من نتائج البحث.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    كائن JSON اختياري يُخزن مع الجلسة (عندما يكون
                    `save_api_request=true`) ويُعاد في الاستجابة. في طلبات
                    multipart، أرسله كحقل سلسلة نصية بترميز JSON — حيث يتم
                    تحليله إلى كائن.
                  example:
                    flow: dedup_check
            example:
              user_image: (binary JPEG/PNG selfie)
              search_type: most_similar
              rotate_image: false
              save_api_request: true
              vendor_data: user-123
              metadata:
                flow: dedup_check
      responses:
        '200':
          description: >-
            اكتمل البحث بالوجه. يحتوي الحقل `face_search.matches` على ما يصل إلى
            5 وجوه مشابهة مرتبة حسب درجة التشابه؛ وتشير المصفوفة الفارغة إلى عدم
            تجاوز أي وجه مُسجّل للحد الأدنى من التشابه. تكون الحالة `status` هي
            `Declined` فقط عند التطابق مع قائمة الحظر — أما التطابقات المكررة
            وحدها فترجع `Approved`، لذا تحقّق من `matches` و`warnings`، وليس من
            `status` فقط. عندما تكون `save_api_request=true`، يكون `request_id`
            هو معرّف الجلسة المحفوظة. يحمل كل تطابق `source` (سواء `session`، أو
            `imported`، أو `list_entry`، أو `retained_template`)،
            و`vendor_user_id`، و`biometric_template_id`؛ ويأتي التطابق من نوع
            `retained_template` من قالب بيومتري خالٍ من الصور يتم الاحتفاظ به
            بعد حذف الجلسة المصدرية وتكون حقول الجلسة و`match_image_url`
            و`user_details` الخاصة به بقيمة `null`.
          content:
            application/json:
              examples:
                Blocklist hit (Declined):
                  summary: الوجه يطابق وجهاً مدرجاً في قائمة الحظر
                  value:
                    request_id: a1b2c3d4-e5f6-7890-1234-567890abcdef
                    face_search:
                      status: Declined
                      total_matches: 1
                      matches:
                        - session_id: 882c42d5-8a4d-4d20-8080-a22f57822c86
                          session_number: 323442
                          similarity_percentage: 99.99
                          source: session
                          vendor_data: user-1
                          verification_date: '2025-01-01T00:00:00Z'
                          user_details:
                            full_name: Jane Marie Doe
                            document_type: ID
                            document_number: X1234567
                          match_image_url: https://<media-host>/face/3f6a1c2e/reference.jpg
                          status: Approved
                          is_blocklisted: true
                          is_allowlisted: false
                          api_service: null
                          vendor_user_id: 2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f
                          biometric_template_id: null
                      user_image:
                        entities:
                          - bbox:
                              - 40
                              - 40
                              - 120
                              - 120
                            confidence: 0.732973
                        best_angle: 0
                      warnings:
                        - risk: FACE_IN_BLOCKLIST
                          feature: LIVENESS
                          additional_data:
                            blocklisted_session_id: 882c42d5-8a4d-4d20-8080-a22f57822c86
                            blocklisted_session_number: 323442
                            api_service: null
                          log_type: error
                          short_description: Face in blocklist
                          long_description: >-
                            The system identified a face in the blocklist, which
                            means the face is not allowed to be verified.
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T01:04:42.763237+00:00'
                Duplicate found (Approved):
                  summary: >-
                    ظهر الوجه بالفعل في جلسة مقبولة أخرى — معلوماتي فقط، بدون
                    رفض
                  value:
                    request_id: 5e0c3a1f-7b2d-4c8e-9f10-2a3b4c5d6e7f
                    face_search:
                      status: Approved
                      total_matches: 1
                      matches:
                        - session_id: 1f2e3d4c-5b6a-7980-1122-334455667788
                          session_number: 1024
                          similarity_percentage: 87.42
                          source: session
                          vendor_data: user-9
                          verification_date: '2025-11-20T09:15:00Z'
                          user_details: null
                          match_image_url: https://<media-host>/face/9c8b7a6d/reference.jpg
                          status: Approved
                          is_blocklisted: false
                          is_allowlisted: false
                          api_service: PASSIVE_LIVENESS
                          vendor_user_id: 2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f
                          biometric_template_id: null
                      user_image:
                        entities:
                          - bbox:
                              - 40
                              - 40
                              - 120
                              - 120
                            confidence: 0.732973
                        best_angle: 0
                      warnings:
                        - risk: DUPLICATED_FACE
                          feature: LIVENESS
                          additional_data:
                            duplicated_session_id: 1f2e3d4c-5b6a-7980-1122-334455667788
                            duplicated_session_number: 1024
                            api_service: PASSIVE_LIVENESS
                          log_type: information
                          short_description: Duplicated face from other approved session
                          long_description: >-
                            The system identified a duplicated face from another
                            approved session, requiring further investigation.
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T01:04:42.763237+00:00'
                No matches (Approved):
                  summary: لم يتجاوز أي وجه مسجل الحد الأدنى للتشابه
                  value:
                    request_id: 9d8c7b6a-5f4e-3d2c-1b0a-998877665544
                    face_search:
                      status: Approved
                      total_matches: 0
                      matches: []
                      user_image:
                        entities:
                          - bbox:
                              - 40
                              - 40
                              - 120
                              - 120
                            confidence: 0.732973
                        best_angle: 0
                      warnings: []
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T01:04:42.763237+00:00'
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: >-
                      معرّف الجلسة المحفوظة عندما تكون `save_api_request=true`
                      (يمكن استخدامه مع `GET
                      /v3/session/{sessionId}/decision/`)؛ وإلا فسيكون UUID
                      ارتباط مؤقت.
                  face_search:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                        description: >-
                          `Declined` فقط عند إطلاق تحذير `FACE_IN_BLOCKLIST` أو
                          `POSSIBLE_FACE_IN_BLOCKLIST`. لا تؤدي التطابقات
                          المكررة وتحذيرات الوجوه المتعددة إلى الرفض أبداً.
                      total_matches:
                        type: integer
                        description: عدد الإدخالات في `matches` (0–5).
                        example: 1
                      matches:
                        type: array
                        maxItems: 5
                        description: >-
                          ما يصل إلى 5 وجوه من فهرس البحث بالوجه الخاص بك والتي
                          تتجاوز الحد الأدنى للتشابه، مرتبة حسب التشابه (مع
                          تصنيف الإدخالات المدرجة في قائمة الحظر أولاً عندما
                          تكون `search_type=blocklisted_or_approved`). تكون
                          فارغة عندما لا يكون أي وجه مسجل مشابهاً بدرجة كافية.
                        items:
                          type: object
                          properties:
                            session_id:
                              type: string
                              format: uuid
                              nullable: true
                              description: >-
                                معرّف جلسة التحقق التي ينتمي إليها الوجه
                                المطابق. يكون `null` عندما يكون `source` هو
                                `imported` أو `list_entry` أو
                                `retained_template`.
                              example: 882c42d5-8a4d-4d20-8080-a22f57822c86
                            session_number:
                              type: integer
                              nullable: true
                              description: >-
                                رقم الجلسة السهل القراءة المعروض في Business
                                Console. يكون `null` لحالات التطابق التي لا تخص
                                جلسة.
                              example: 323442
                            similarity_percentage:
                              type: number
                              format: float
                              minimum: 0
                              maximum: 100
                              description: >-
                                التشابه بين الوجه المُرسَل والوجه المطابق
                                (0–100).
                              example: 99.99
                            source:
                              type: string
                              enum:
                                - session
                                - imported
                                - list_entry
                                - retained_template
                              description: >-
                                مصدر تسجيل الوجه المتطابق: `session` — جلسة تحقق
                                أو استدعاء API مستقل ومحفوظ؛ `imported` — وجه تم
                                رفعه مباشرة إلى ملف تعريف المستخدم؛ `list_entry`
                                — وجه مرتبط بإحدى قوائمك؛ `retained_template` —
                                قالب بيومتري بدون صورة مخزّن لدى المستخدم،
                                ومُدرج تحت `/v3/biometric-templates/`.
                            vendor_data:
                              type: string
                              nullable: true
                              description: >-
                                `vendor_data` للجلسة المطابقة أو المستخدم
                                المرتبط للوجوه المستوردة والوجوه ذات القوالب
                                المحتفظ بها.
                              example: user-1
                            vendor_user_id:
                              type: string
                              format: uuid
                              nullable: true
                              description: >-
                                معرّف المستخدم المرتبط. يكون `null` لمدخلات
                                القوائم وتطابقات الجلسات غير المرتبطة بمستخدم.
                              example: 2f7c1a9e-4b28-4a6d-97f1-83576f80e1b4
                            biometric_template_id:
                              type: string
                              format: uuid
                              nullable: true
                              description: >-
                                معرّف القالب البيومتري المحتفظ به. يتم تعيينه
                                فقط عندما يكون `source` هو `retained_template`؛
                                و`null` بخلاف ذلك.
                              example: null
                            verification_date:
                              type: string
                              format: date-time
                              nullable: true
                              description: >-
                                متى تم التقاط الوجه المطابق في الأصل، أو متى تم
                                إنشاء قالب محتفظ به (`YYYY-MM-DDThh:mm:ssZ`).
                                وتكون `null` لتطابقات `list_entry`.
                              example: '2025-01-01T00:00:00Z'
                            user_details:
                              type: object
                              nullable: true
                              description: >-
                                بيانات الهوية المستخرجة أثناء التحقق من مستندات
                                الجلسة المتطابقة. تكون `null` عندما لا تحتوي
                                الجلسة المتطابقة على بيانات مستند (مثل جلسات كشف
                                الحيوية فقط)، وتكون دائماً `null` للتطابقات من
                                نوع `retained_template`. أما بالنسبة للتطابقات
                                ذات `source: imported`، فيتم ملؤها من ملف تعريف
                                المستخدم بدلاً من ذلك: يتم تعيين `full_name`،
                                وتكون قيمة `document_type`/`document_number` هي
                                null.
                              properties:
                                full_name:
                                  type: string
                                  nullable: true
                                  example: Jane Marie Doe
                                document_type:
                                  type: string
                                  nullable: true
                                  example: ID
                                document_number:
                                  type: string
                                  nullable: true
                                  example: X1234567
                            match_image_url:
                              type: string
                              nullable: true
                              description: >-
                                رابط URL محدد الصلاحية زمنيًا
                                (`https://<media-host>/...`) للصورة المرجعية
                                للوجه المطابق عندما يكون
                                `save_api_request=true`. أما مع
                                `save_api_request=false`، فهذا مسار تخزين داخلي
                                لا يمكن تنزيله مباشرةً. يكون دائمًا `null`
                                للمطابقات من نوع `retained_template` لأن القوالب
                                المحتفظ بها لا تحتوي على صورة.
                              example: https://<media-host>/face/3f6a1c2e/reference.jpg
                            status:
                              type: string
                              nullable: true
                              description: >-
                                حالة الجلسة المتطابقة (`Approved`، `Declined`،
                                `In Review`، …). تكون `null` للتطابقات من نوع
                                `imported`/`list_entry`.
                              example: Approved
                            is_blocklisted:
                              type: boolean
                              description: >-
                                تكون `true` عندما يكون الوجه المطابق مدرجاً في
                                قائمة حظر الوجوه الخاصة بك. أي مطابقة مشابهة
                                بدرجة كافية ومدرجة في قائمة الحظر تؤدي إلى رفض
                                البحث.
                            is_allowlisted:
                              type: boolean
                              description: >-
                                تكون `true` عندما يكون الوجه المطابق مدرجاً في
                                إحدى قوائم السماح الخاصة بك. تؤدي المطابقات في
                                قائمة السماح إلى منع تحذيرات التكرار.
                            api_service:
                              type: string
                              nullable: true
                              description: >-
                                يتم تعيينه عندما يتم تسجيل الوجه المطابق عبر
                                استدعاء API مستقل (مثل `PASSIVE_LIVENESS`)؛
                                وتكون القيمة `null` لجلسات التحقق العادية
                                والوجوه المستوردة.
                              example: null
                      user_image:
                        type: object
                        description: >-
                          نتائج كشف الوجه للصورة المُرسلة. تتضمن المدخلات هنا
                          الحقلين `bbox` و`confidence` فقط.
                        properties:
                          entities:
                            type: array
                            description: >-
                              إدخال واحد لكل وجه مكتشف. ويتم البحث باستخدام
                              الوجه الأكبر.
                            items:
                              type: object
                              properties:
                                bbox:
                                  type: array
                                  items:
                                    type: integer
                                  minItems: 4
                                  maxItems: 4
                                  description: >-
                                    المربع المحيط `[x_min, y_min, x_max, y_max]`
                                    بالبكسل.
                                  example:
                                    - 40
                                    - 40
                                    - 120
                                    - 120
                                confidence:
                                  type: number
                                  format: float
                                  minimum: 0
                                  maximum: 1
                                  description: درجة الثقة في كشف الوجه (0–1).
                                  example: 0.732973
                          best_angle:
                            type: integer
                            description: >-
                              زاوية التدوير (بالدرجات) التي حققت أفضل كشف للوجه؛
                              ولا تكون غير صفرية إلا عندما يصحح
                              `rotate_image=true` الاتجاه. لا تكون null أبداً في
                              هذا الـ endpoint (تكون قيمتها الافتراضية 0 إذا
                              أغفلها النموذج).
                            example: 0
                      warnings:
                        type: array
                        description: >-
                          إشارات المخاطر. تؤدي `FACE_IN_BLOCKLIST` /
                          `POSSIBLE_FACE_IN_BLOCKLIST` (`error`) إلى رفض البحث؛
                          بينما تُعد `MULTIPLE_FACES_DETECTED` (`warning`)
                          و`DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE`
                          (`information`) إشارات استرشادية.
                        items:
                          type: object
                          properties:
                            risk:
                              type: string
                              enum:
                                - MULTIPLE_FACES_DETECTED
                                - FACE_IN_BLOCKLIST
                                - POSSIBLE_FACE_IN_BLOCKLIST
                                - DUPLICATED_FACE
                                - POSSIBLE_DUPLICATED_FACE
                              description: رمز مخاطر مقروء آلياً.
                            feature:
                              type: string
                              enum:
                                - LIVENESS
                              description: >-
                                الميزة التي أصدرت التحذير. دائماً `LIVENESS` في
                                هذا الـ endpoint.
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                `null` لـ `MULTIPLE_FACES_DETECTED`. تحمل
                                التطابقات مع قائمة الحظر
                                `{blocklisted_session_id,
                                blocklisted_session_number, api_service}`؛ بينما
                                تحمل التطابقات المكررة `{duplicated_session_id,
                                duplicated_session_number, api_service}` التي
                                تشير إلى أول جلسة متطابقة.
                            log_type:
                              type: string
                              enum:
                                - error
                                - warning
                                - information
                              description: >-
                                مستوى الخطورة. تحذيرات `error` تنقل `status` إلى
                                `Declined`؛ وإدخالات `warning` و`information`
                                استشارية ولا تؤدي إلى الرفض بمفردها أبداً.
                            short_description:
                              type: string
                              description: ملخص للمخاطر في سطر واحد مقروء للبشر.
                            long_description:
                              type: string
                              description: تفسير سهل القراءة للمخاطر.
                  vendor_data:
                    type: string
                    nullable: true
                    description: نسخة مطابقة من `vendor_data` التي أرسلتها، أو `null`.
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: نسخة مطابقة من كائن `metadata` الذي أرسلته، أو `null`.
                  created_at:
                    type: string
                    format: date-time
                    description: >-
                      طابع زمني بتنسيق ISO 8601 (بالتوقيت العالمي المنسق UTC)
                      لوقت إنشاء الاستجابة، مثل
                      `2026-06-12T01:04:42.763237+00:00`.
        '400':
          description: >-
            خطأ في التحقق. يتم إرجاعه عندما تكون `user_image` مفقودة، أو يتجاوز
            حجمها 5 MB، أو يكون امتدادها غير مدعوم، أو عند **عدم اكتشاف أي وجه**
            في الصورة المُرسلة. تستخدم أخطاء الحقول غلاف `{field: [messages]}`
            الخاص بـ DRF؛ بينما تستخدم حالات فشل اكتشاف الوجه `{"error": ...}`.
          content:
            application/json:
              examples:
                No face detected:
                  summary: >-
                    تم فك ترميز الصورة بنجاح ولكنها لا تحتوي على أي وجه يمكن
                    اكتشافه
                  value:
                    error: No face detected in the image
                Missing image:
                  summary: لم يتم تضمين `user_image` في بيانات النموذج
                  value:
                    user_image:
                      - No file was submitted.
                Unsupported file extension:
                  summary: امتداد الملف خارج tiff/jpg/jpeg/png/webp
                  value:
                    user_image:
                      - >-
                        File extension “txt” is not allowed. Allowed extensions
                        are: tiff, jpg, jpeg, png, webp.
                File too large:
                  summary: يتجاوز الملف المرفوع حد 5 ميجابايت
                  value:
                    user_image:
                      - File size should not exceed 5 MB
        '403':
          description: >-
            تم رفض الإذن. يُرجع عند فقدان الرأس `x-api-key`، وأيضاً عندما لا
            يتمكن رصيد المؤسسة الطالبة من تغطية الاستدعاء؛ ويُرجع المفتاح الخاطئ
            أو الملغى أو منتهي الصلاحية `401`. يؤدي المفتاح المفقود إلى إرجاع
            `403` مع `{"detail": ...}`؛ ويؤدي المفتاح الخاطئ أو الملغى أو منتهي
            الصلاحية إلى إرجاع `401`. يُرجع نقص الرصيد `403` مع `{"error": ...}`
            قبل إجراء أي معالجة للصور.
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: لا يوجد رأس `x-api-key`، أو أن المفتاح غير صالح/ملغى
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: رصيد المؤسسة لا يمكنه تغطية تكلفة الاستدعاء
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '429':
          description: >-
            تم تجاوز حد المعدل. تشترك نقاط endpoint الخاصة بـ POST/PATCH/DELETE
            في ميزانية قدرها 300 طلب كتابة في الدقيقة لكل مفتاح API (إنشاء
            المعاملات واستيعاب الأحداث لهما ميزانية منفصلة تبلغ 600). تتضمن
            الاستجابة رؤوس `X-RateLimit-Limit` و`X-RateLimit-Remaining`
            و`X-RateLimit-Reset` و`Retry-After`.
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: أكثر من 300 طلب كتابة في الدقيقة الحالية
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST 'https://verification.didit.me/v3/face-search/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -F 'user_image=@./selfie.jpg' \
              -F 'search_type=most_similar' \
              -F 'save_api_request=true' \
              -F 'vendor_data=user-123'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.face_search.search(
                user_image=open("user_image.jpg", "rb"),
                search_type="most_similar",
                rotate_image=False,
                save_api_request=True,
                vendor_data="user-123",
                metadata={"flow": "dedup_check"},
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit, { fileFromPath } from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.faceSearch.search({
              user_image: await fileFromPath("user_image.jpg"),
              search_type: "most_similar",
              rotate_image: false,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "dedup_check" },
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FaceSearch.Search(ctx, didit.FaceSearchSearchParams{\n\tUserImage:      didit.FileFromPath(\"user_image.jpg\"),\n\tSearchType:     didit.Some(didit.FaceSearchSearchParamsSearchType(\"most_similar\")),\n\tRotateImage:    didit.Bool(false),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData:     didit.String(\"user-123\"),\n\tMetadata:       didit.Some(map[string]any{\"flow\": \"dedup_check\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.nio.file.Path;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.FaceSearchSearchParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.faceSearch().search(FaceSearchSearchParams.builder()
                    .userImage(Path.of("user_image.jpg"))
                    .searchType(FaceSearchSearchParams.SearchType.of("most_similar"))
                    .rotateImage(false)
                    .saveApiRequest(true)
                    .vendorData("user-123")
                    .metadata(Map.of("flow", "dedup_check"))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;
            use Didit\File;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->faceSearch->search([
                'user_image' => File::fromPath('user_image.jpg'),
                'search_type' => 'most_similar',
                'rotate_image' => false,
                'save_api_request' => true,
                'vendor_data' => 'user-123',
                'metadata' => ['flow' => 'dedup_check'],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

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

            result = didit.face_search.search(
              user_image: Pathname("user_image.jpg"),
              search_type: "most_similar",
              rotate_image: false,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "dedup_check" }
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.FaceSearch.SearchAsync(new
            FaceSearchSearchParams

            {
                UserImage = FileUpload.FromPath("user_image.jpg"),
                SearchType = new FaceSearchSearchParamsSearchType("most_similar"),
                RotateImage = false,
                SaveApiRequest = true,
                VendorData = "user-123",
                Metadata = new Dictionary<string, object> { ["flow"] = "dedup_check" },
            });

            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.