ابنِ مع Zoi ID
واجهتا API على مضيف واحد، وعملاء محددو الأنواع بست لغات، ومسار مُستضاف، وبيئة اختبار. الدليل الكامل متاح للقراءة، ومفاتيح بيئة الاختبار تأتي مع الوصول المبكر.
عنوان URL الأساسيhttps://kyc.zoi.network
البدء السريع
- 1
أنشئ جلسة
يستدعي خادمك
POST /v1/partner/sessionsبمفتاح الشريك. - 2
شغّل المسار
مرّر رمز العميل إلى SDK، أو افتح
verificationUrlفي متصفح. - 3
استقبل النتيجة
تحقق من توقيع Webhook، ثم احفظ معرّف الهوية وحالتها.
curl https://kyc.zoi.network/v1/partner/sessions \
-H "Authorization: Bearer $ZOI_ID_PARTNER_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: signup-user_42" \
-d '{ "externalUserId": "user_42", "level": "standard", "appId": "com.example.app" }'واجهتا API
واجهة الشركاء
من خادم إلى خادم، تحت /v1/partner. أرسل مفتاح الشريك كرمز Bearer. لا تضعه في أي تطبيق أبدًا.
واجهة العميل
تستخدمها حزمة SDK، تحت /v1/client. ترسل رمز عميل صالحًا لجلسة واحدة لمدة 60 دقيقة.
القواعد
- الأوقات بالمللي ثانية منذ epoch، في الحقول التي تنتهي أسماؤها بـ
At. - التواريخ بصيغة
YYYY-MM-DD. الأجزاء غير المعروفة تُكتبXX، مثل1990-XX-XX. - طلبات POST التي تنشئ أو تقرر شيئًا تقبل الترويسة
Idempotency-Key. تُحفظ المفاتيح 24 ساعة. - تغييرات الجلسة ترسل رقم المراجعة المتوقع. إذا تغيّر، تحصل على
revision_conflict.
مسار الجلسة
ينشئ خادمك الجلسة. تنفذ حزمة SDK الخطوات. يتحقق الخادم من الترتيب ويرد بـ step_not_allowed عندما تأتي خطوة مبكرًا.
1. أنشئ جلسة من خادمك
استدعاؤها مرة أخرى للمستخدم نفسه يستأنف الجلسة المفتوحة ويعطي رمز عميل جديدًا.
POST /v1/partner/sessions
Authorization: Bearer <partner key>
Content-Type: application/json
Idempotency-Key: 6f1c2a9e-signup-42
{
"externalUserId": "user_42",
"level": "standard",
"locale": "en",
"appId": "com.example.app"
}
200 OK
{
"sessionId": "ses_...",
"clientToken": "...",
"clientTokenExpiresAt": 1767225600000,
"status": "created",
"apiBaseUrl": "https://kyc.zoi.network",
"resumed": false
}2. الخطوات التي تنفذها SDK
- 01
قراءة الجلسة والخطوات المتبقية.
GET /v1/client/session
- 02
تسجيل الموافقة، مع الاختيار المنفصل والاختياري لمقارنة الوجه.
POST /v1/client/consent
- 03
فحص التطبيق والجهاز. والنتيجة جزء من القرار.
POST /v1/client/attestation/challenge, POST /v1/client/attestation
- 04
إرسال الوثيقة: قراءة الشريحة بعد مسح MRZ، أو إرسال صور.
POST /v1/client/document/mrz-scan, POST /v1/client/document/chip/challenge, POST /v1/client/document/chip or POST /v1/client/document/photos
- 05
تسجيل فيديو قصير واحد بالكاميرا الأمامية بينما يعرض التطبيق حركات الرأس.
POST /v1/client/liveness/challenge, POST /v1/client/liveness
- 06
إرسال دولة الإقامة، والعنوان في المستوى المعزز.
POST /v1/client/profile
- 07
فقط مع متطلب العنوان: ارفع وثيقة، ثم أكّد العنوان. تُتخطى إذا كانت وثيقة الهوية قد قدّمت العنوان أصلًا.
POST /v1/client/address/document, POST /v1/client/address/confirm
- 08
فقط مع متطلب الأموال: احفظ الإجابات، وأضف الوثائق إذا طلبتها السياسة، ثم أكمل الخطوة.
POST /v1/client/funds/answers, POST /v1/client/funds/document, POST /v1/client/funds/remove, POST /v1/client/funds/complete
- 09
الإجابة عن سؤالين: هل الشخص معرض سياسيًا، وهل يتصرف لحسابه الخاص.
POST /v1/client/declarations
- 10
الإرسال برقم المراجعة الحالي.
POST /v1/client/submit
يمكن للمستخدم أيضًا أن يطلب من شخص مراجعة نتيجة آلية (POST /review-request) أو أن يسحب موافقته، فتُلغى الجلسة وتُحذف ملفاتها فورًا (POST /withdraw).
إثبات العنوان ومصدر الأموال
أضف requirements إلى POST /v1/partner/sessions للتحقق مما هو أبعد من الهوية. تطلب address إثبات العنوان. وتسأل source_of_funds من أين يأتي المال، وتسأل source_of_wealth أيضًا عن إجمالي الثروة وكيف تكوّنت. القيمتان الخاصتان بالأموال معًا خطوة واحدة، وكلتاهما تُجمع مع address.
POST /v1/partner/sessions
Authorization: Bearer <partner key>
Content-Type: application/json
{
"externalUserId": "user_42",
"level": "standard",
"appId": "com.example.app",
"requirements": ["address", "source_of_funds"],
// Optional. Without them your partner default applies, else ours.
"addressPolicy": { "maxAgeDays": 90, "signedOnly": false },
"fundsPolicy": { "evidence": "optional", "currency": "EUR" }
}سياسات اختيارية
دون سياسة، تُطبَّق إعداداتك الافتراضية كشريك، وإلا فإعداداتنا. وتُنسخ السياسة إلى الجلسة عند إنشائها.
addressPolicy:maxAgeDays(افتراضيًا 90، من 1 إلى 366)، وacceptedTypes(افتراضيًا: وثائق الخدمات والاتصالات والبنوك، والوثائق الضريبية، والرسائل الحكومية، وشهادات الإقامة)، وsignedOnly(افتراضيًا false).fundsPolicy:questions، وevidence(noneأوoptionalأوrequired، افتراضيًاnone)، وacceptedTypes، وmaxAgeDays(افتراضيًا 180)، وcurrency(ISO 4217، افتراضيًا USD)، وbracketsللنطاقات.- الجلسة المفتوحة بمتطلبات أخرى التي لم تُرسل بعد تُلغى وتبدأ جلسة جديدة، كما عند تغيير المستوى.
- اختبر كل نتيجة بسيناريوهات بيئة الاختبار مثل
address_signed_pdfوaddress_document_reviewوfunds_signed_documentsوfunds_review.
جلسات المتابعة
تحقّق من المتطلبات فقط لمستخدم هويته نشطة لديك أصلًا. أرسل reuseIdentity: true مع requirements.
- يوافق المستخدم ويكمل الخطوات الجديدة فقط. لا يُطلب منه من جديد وثيقة ولا سيلفي ولا إقرارات.
- عند الموافقة تحتفظ الهوية بمعرّفها وتاريخ التحقق وصلاحيتها، وتحصل على النتيجة الجديدة. وتتلقى
session.approvedوidentity.updated. - دون هوية نشطة، يرد الاستدعاء بـ 409
step_not_allowed. - ابدأها من قواعد المخاطر الخاصة بك، مثل إيداع كبير أو علامة PEP أو دولة عالية المخاطر. وتبقى قواعدك في خادمك، في مكان واحد.
POST /v1/partner/sessions
Authorization: Bearer <partner key>
Content-Type: application/json
Idempotency-Key: edd-user_42-2026-11
{
"externalUserId": "user_42",
"appId": "com.example.app",
"requirements": ["source_of_funds", "source_of_wealth"],
"reuseIdentity": true,
"fundsPolicy": { "evidence": "required" }
}
// No active identity for user_42:
409 { "error": { "code": "step_not_allowed", ... } }النتائج والصلاحيات
تحمل الجلسات المعتمدة address وfunds، وتحتفظ الهوية بأحدث نتيجة لكل منهما. حقول الملخص تأتي مع كل صلاحية. أما التفاصيل فتحتاج إلى صلاحية.
- الصلاحية
address: أسطر العنوان. ومن دونها تحصل علىverifiedوmethodوevidenceLevelوdocumentTypeوdocumentDateوverifiedAtوcountry. - الصلاحية
financial_data:answersوdocumentsوfindings. ومن دونها تحصل علىkindsوevidenceLevelوreviewedوdocumentCountوverifiedAt. ولا تدخل أبدًا فيeligibility. - قيمة
evidenceLevelهيhighأوmediumأوlowأوnone. طرق العنوان، من الأقوى إلى الأضعف:walletوid_documentوsigned_pdfوofficial_codeوdocument_reviewوdeclared. - لا تُرسل الوثائق عبر API. يستطيع الأعضاء ذوو دور الامتثال عرض صفحات وثائق مصدر الأموال في لوحة التحكم عندما تملك البيئة صلاحية
financial_data. وكل عملية عرض تُسجَّل.
"session": {
"id": "ses_...",
"status": "approved",
"requirements": ["address", "source_of_funds"],
"reusesIdentity": false,
"address": {
"verified": true,
"method": "signed_pdf",
"evidenceLevel": "high",
"documentType": "bank_statement",
"documentDate": "2026-10-14",
"verifiedAt": 1767225600000,
"country": "DE",
// scope "address"
"address": { "line1": "Musterstrasse 12", "city": "Berlin", "postalCode": "10115", "country": "DE" }
},
"funds": {
"kinds": ["source_of_funds"],
"evidenceLevel": "medium",
"reviewed": true,
"documentCount": 2,
"verifiedAt": 1767225600000,
// scope "financial_data"
"answers": {
"employmentStatus": "employed",
"income": { "min": 50000, "max": 100000, "currency": "EUR" },
"sources": ["salary", "savings"],
...
},
"documents": [
{ "documentType": "payslip", "documentDate": "2026-10-31", "amount": 5200, "currency": "EUR",
"signature": "valid", "signedByKnownIssuer": true, "nameMatch": "match", "findings": [], ... },
...
],
"findings": []
}
}مسار الويب
لا تستخدم SDK؟ أرسل المستخدم إلى صفحتنا المستضافة. تستخدم نفس الواجهة البرمجية ونفس الفحوصات ونفس قائمة المراجعة.
1. احصل على الرابط
يعيد POST /v1/partner/sessions القيمة verificationUrl. مرّر redirectUrl لإعادة المستخدم إليك عند الانتهاء. يجب أن يبدأ بأحد أصول إعادة التوجيه المسجلة لديك.
POST /v1/partner/sessions
Authorization: Bearer <partner key>
Content-Type: application/json
{
"externalUserId": "user_42",
"level": "standard",
"locale": "en",
"appId": "com.example.app",
"redirectUrl": "https://example.com/kyc/done"
}
200 OK
{
"sessionId": "ses_...",
"clientToken": "...",
"verificationUrl": "https://kyc.zoi.network/verify/#token=...&lang=en",
...
}- رمز العميل موجود في جزء الـ fragment من الرابط، بعد
#. لا ترسل المتصفحات هذا الجزء إلى أي خادم أبدًا، لذا لا يظهر الرمز في السجلات ولا في ترويسةReferer. تقرأه الصفحة، ثم تحذفه من شريط العنوان وتحتفظ به في الذاكرة فقط. - أضف
langإلى الـ fragment لاختيار إحدى اللغات الـ 19. بدونه تستخدم الصفحة لغة المتصفح. - إعادة التحميل تُفقد الرمز. أنشئ رابطًا جديدًا للجلسة نفسها من الخادم الخلفي لديك.
- ترسل الصفحة
channel: "web"مع الموافقة. المتصفحات لا تستطيع قراءة شرائح الهوية، لذا تستخدم جلسات الويب صور الوثيقة أو محفظة هوية رقمية. وتتخطى فحص الجهاز، وصور الوثائق القادمة من الويب يحسمها دائمًا مراجع مدرب. - على الكمبيوتر، تعرض الصفحة رمز QR حتى يتابع المستخدم على هاتفه.
2. عندما ينتهي المستخدم
عند انتهاء المسار (أُرسل أو أُلغي أو وصل إلى حالة نهائية)، ترسل الصفحة هذه الرسالة إلى كل ما يوجد من التالي: window.ReactNativeWebView وwindow.webkit.messageHandlers.zoiId وwindow.ZoiIdAndroid وwindow.opener. ثم تفتح redirectUrl مع إضافة zoiIdSession وzoiIdStatus.
لا تثق أبدًا بالرسالة أو بمعاملات إعادة التوجيه. ثق فقط بالـ webhook الخاص بك أو بـ GET /v1/partner/sessions/:id.
// Sent to each bridge that exists:
// window.ReactNativeWebView.postMessage(JSON string)
// window.webkit.messageHandlers.zoiId.postMessage(object)
// window.ZoiIdAndroid.postMessage(JSON string)
// window.opener.postMessage(object, "<origin of your redirectUrl>")
// (popups only, and only when the session has a redirectUrl)
{
"source": "zoi-id",
"type": "finished", // or "cancelled"
"sessionId": "ses_...",
"status": "processing" // the session status at that moment
}
// Then, if redirectUrl was set (the page uses the one stored with the
// session, never one from the address bar):
https://example.com/kyc/done?zoiIdSession=ses_...&zoiIdStatus=processing3. إعدادات الـ webview
Android WebView
فعّل javaScriptEnabled وdomStorageEnabled، واضبط mediaPlaybackRequiresUserGesture على false. في WebChromeClient، امنح onPermissionRequest للمورد RESOURCE_VIDEO_CAPTURE بعد أن يحصل تطبيقك على إذن CAMERA. أضف منتقي ملفات لبديل الصور.
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
// Only after your app holds Manifest.permission.CAMERA.
if (request.resources.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
request.grant(arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
} else {
request.deny()
}
}
override fun onShowFileChooser(
view: WebView, callback: ValueCallback<Array<Uri>>, params: FileChooserParams,
): Boolean {
// Open a picker and pass the result to callback (photo fallback).
return true
}
}iOS WKWebView
iOS 14.3 أو أحدث. اضبط allowsInlineMediaPlayback على true وأضف NSCameraUsageDescription إلى تطبيقك. في iOS 15 وما بعده يمكنك تحديد إذن الكاميرا في UI delegate.
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
let webView = WKWebView(frame: .zero, configuration: config)
webView.uiDelegate = self // iOS 15+: decide camera access below
func webView(_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
type: WKMediaCaptureType,
decisionHandler: @escaping (WKPermissionDecision) -> Void) {
decisionHandler(origin.host == "kyc.zoi.network" ? .grant : .deny)
}
// Info.plist: NSCameraUsageDescriptionReact Native WebView
اضبط mediaCapturePermissionGrantType="grant" وallowsInlineMediaPlayback وjavaScriptEnabled. يحتاج تطبيقك إلى إذن الكاميرا.
<WebView
source={{ uri: verificationUrl }}
javaScriptEnabled
allowsInlineMediaPlayback
mediaCapturePermissionGrantType="grant"
onMessage={(event) => {
const message = JSON.parse(event.nativeEvent.data);
if (message.source === "zoi-id") {
// Close the webview, then ask your backend for the real status.
}
}}
/>الـ iframe غير مدعوم، بسبب أذونات الكاميرا وخطر clickjacking. استخدم تبويب متصفح أو نافذة منبثقة أو webview.
الحالات
الجلسة
created- الجلسة موجودة، ولم يُرفع شيء بعد.
in_progress- تمت الموافقة، والخطوات قيد الرفع.
processing- تم الإرسال، والفحوص جارية.
review- بانتظار مراجع مدرب.
approved- نهائية. تم التحقق من الهوية.
rejected- نهائية. راجع رموز الأسباب.
resubmit- على المستخدم إعادة الخطوات الموجودة في requiredSteps.
expired- لم يصدر قرار نهائي في الوقت المحدد.
cancelled- ألغاها الشريك أو المستخدم أو عملية حذف.
الهوية
active- قابلة للاستخدام.
suspended- معلّقة، مثلًا بعد ظهور تطابق محتمل جديد مع العقوبات.
expired- انتهت صلاحية الوثيقة أو فترة التحقق. جلسة جديدة تعيد التحقق.
revoked- نهائية.
SDK
تعطيك حزمة SDK لـ React Native (Expo) عميل API محدد الأنواع، وقراءة الشريحة عبر NFC، وفحوص الجهاز. وهي بلا واجهة، فيحتفظ تطبيقك بالتحكم الكامل في شاشاته وكاميرته. ولخوادمك، استخدم العملاء محددي الأنواع لـ TypeScript وPython وGo وPHP وJava وRuby.
import { ZoiIdClient, nextStep } from "@zoi/id-sdk";
// clientToken and apiBaseUrl come from your backend (POST /v1/partner/sessions).
const client = new ZoiIdClient({ baseUrl: apiBaseUrl, clientToken });
const session = await client.getSession();
switch (nextStep(session)) {
case "consent": /* show the notice and the biometric choice */ break;
case "document": /* chip read or photos */ break;
case "liveness": /* record the video */ break;
case "address": /* upload a document, then confirm the address */ break;
case "funds": /* answers, then documents when the policy asks */ break;
case "submit": await client.submit(session.revision); break;
case "done": /* wait for your backend to get the webhook */ break;
}Webhooks
نرسل Webhook عندما تتغير جلسة أو هوية. تحقق دائمًا من التوقيع قبل أن تثق بالمحتوى.
- كل Webhook يحمل الترويسة
Zoi-Id-Signature:t=unix seconds,v1=hex. v1هو HMAC-SHA256 للنصt.raw bodyباستخدام سر Webhook الخاص بك. استخدم المحتوى الخام قبل أي تحليل لـ JSON.- أثناء تغيير السر، تحمل الترويسة قيمة
v1لكل سر نشط. اقبل Webhook إذا تطابقت أي واحدة منها. - ارفضه إذا كان
tيبعد أكثر من 300 ثانية عن الوقت الحالي. - تُعاد محاولة التسليمات الفاشلة لمدة 72 ساعة. كل محاولة تُوقّع من جديد بقيمة
tجديدة. - الهويات تحمل
revision. طبّق الحدث فقط إذا كانت مراجعته أحدث من التي حفظتها.
POST <your webhook URL>
Zoi-Id-Signature: t=1767225600,v1=5f2b...e9
{
"v": 1,
"eventId": "evt_...",
"type": "identity.suspended",
"createdAt": 1767225600000,
"object": "identity",
"externalUserId": "user_42",
"identity": {
"identityId": "idn_...",
"revision": 7,
"status": "suspended",
"level": "standard",
"verifiedAt": 1764547200000,
"validUntil": 1859155200000,
"ageOver18": true,
"captureMethod": "nfc"
}
}أنواع الأحداث
session.processingsession.reviewsession.approvedsession.rejectedsession.resubmitsession.expiredsession.cancelledidentity.updatedidentity.suspendedidentity.reinstatedidentity.expiredidentity.revoked
التحقق من التوقيع بـ TypeScript
import { createHmac, timingSafeEqual } from "node:crypto";
const TOLERANCE_SECONDS = 300;
export function verifyZoiIdSignature(
rawBody: string,
header: string | null,
secret: string,
nowSeconds = Math.floor(Date.now() / 1000),
): boolean {
if (!header) return false;
let t: string | undefined;
const signatures: Buffer[] = [];
for (const part of header.split(",")) {
const [key, value] = part.trim().split("=");
if (!value) continue;
if (key === "t") t = value;
if (key === "v1" && /^[0-9a-f]+$/i.test(value)) signatures.push(Buffer.from(value, "hex"));
}
if (!t || !/^\d+$/.test(t) || signatures.length === 0) return false;
if (Math.abs(nowSeconds - Number(t)) > TOLERANCE_SECONDS) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((sig) => sig.length === expected.length && timingSafeEqual(sig, expected));
}
// Example handler: read the raw body first, parse JSON only after the check.
export async function POST(request: Request) {
const rawBody = await request.text();
const ok = verifyZoiIdSignature(rawBody, request.headers.get("Zoi-Id-Signature"), process.env.ZOI_ID_WEBHOOK_SECRET!);
if (!ok) return new Response("bad signature", { status: 400 });
const event = JSON.parse(rawBody);
// Store event.eventId to skip duplicates, then apply it if the revision is newer.
return new Response(null, { status: 204 });
}التحقق من التوقيع بـ Go
package zoiid
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strconv"
"strings"
"time"
)
const toleranceSeconds = 300
// VerifySignature checks the Zoi-Id-Signature header against the raw body.
func VerifySignature(rawBody []byte, header, secret string, now time.Time) bool {
var t string
var sigs [][]byte
for _, part := range strings.Split(header, ",") {
key, value, ok := strings.Cut(strings.TrimSpace(part), "=")
if !ok || value == "" {
continue
}
switch key {
case "t":
t = value
case "v1":
if b, err := hex.DecodeString(value); err == nil {
sigs = append(sigs, b)
}
}
}
ts, err := strconv.ParseInt(t, 10, 64)
if err != nil || len(sigs) == 0 {
return false
}
if d := now.Unix() - ts; d > toleranceSeconds || d < -toleranceSeconds {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(t + "."))
mac.Write(rawBody)
expected := mac.Sum(nil)
for _, sig := range sigs {
if hmac.Equal(sig, expected) {
return true
}
}
return false
}سجل الأحداث
GET /v1/partner/events يعيد كل أحداث آخر 30 يومًا، الأقدم أولًا. مرّر after مع آخر nextCursor لقراءة الصفحة التالية. استخدمه بعد انقطاع طويل، أو للتأكد من أنك لم تفوّت شيئًا.
GET /v1/partner/events?after=<nextCursor>&limit=100
Authorization: Bearer <partner key>
200 OK
{
"items": [ /* webhook payloads, oldest first */ ],
"nextCursor": "..." // null when there is nothing more
}بلاغات الاحتيال
أخبرنا عندما يتبيّن أن جلسة محسومة كانت احتيالًا، مثلًا بعد استرجاع مدفوعات. تغذّي البلاغات قياسنا للموافقات الخاطئة. ولا تغيّر الجلسة ولا الهوية ولا نتيجة المستخدم.
- الصلاحية
sessions:write. للجلسات المحسومة فقط (المعتمدة أو المرفوضة). وقبل القرار يرد الاستدعاء بـ 409. - الطلب بمحتوى فارغ يبلّغ عن
confirmed_fraudبالفئةother. ويمكن أن تكونstatusأيضًاsuspected_fraud، أوclearedلسحب بلاغك. - الفئات:
forged_documentوimpostorوdeepfake_or_replayوsynthetic_identityوaccount_takeoverوother. لا فئة معcleared. noteنص حر لمحللينا، بحد أقصى 1000 حرف. لا تضع فيه أبدًا أسماء أو أرقام وثائق أو أي بيانات شخصية أخرى.- البلاغ الجديد يرد بـ 201. والبلاغ نفسه مرة أخرى يعيد البلاغ المحفوظ بـ 200. أرسل
Idempotency-Keyلإعادة المحاولة بأمان. بحد أقصى 20 بلاغًا لكل جلسة. - البلاغ نفسه على بُعد نقرة واحدة في صفحة الجلسة بلوحة التحكم.
POST /v1/partner/sessions/ses_.../fraud-reports
Authorization: Bearer <partner key>
Content-Type: application/json
Idempotency-Key: chargeback-8812
{
"status": "confirmed_fraud",
"category": "impostor",
"note": "Chargeback on the first deposit"
}
201 Created
{
"id": "flb_...",
"sessionId": "ses_...",
"status": "confirmed_fraud",
"category": "impostor",
"noteKept": true,
"createdAt": 1767225600000
}الحذف
DELETE /v1/partner/users/:externalUserId يحذف بيانات المستخدم عندما يغلق حسابه أو يطلب الحذف. تذكر الإجابة ما حُذف الآن، وما يُحتفظ به، ولماذا، وحتى متى.
DELETE /v1/partner/users/user_42
Authorization: Bearer <partner key>
200 OK
{
"deleted": ["images", "chip_files", "video", "personal_data", "address"],
"retained": [
{ "category": "dedup_keys", "reason": "fraud_prevention", "until": 1924992000000 },
{ "category": "sanctions_screening_records", "reason": "legal_obligation", "until": 2082758400000 }
],
"backupsPurgedWithinDays": 30
}الأخطاء
لكل الأخطاء الشكل نفسه، ولكل رمز حالة HTTP ثابتة.
{
"error": {
"code": "step_not_allowed",
"message": "This step is not allowed now.",
"requestId": "req_..."
}
}| الرمز | HTTP | المعنى |
|---|---|---|
bad_request | 400 | الطلب لا يطابق العقد. |
unauthorized | 401 | المفتاح أو الرمز مفقود أو خاطئ. |
token_expired | 401 | انتهت صلاحية رمز العميل. أنشئ رمزًا جديدًا من خادمك. |
forbidden | 403 | هذا المفتاح لا يملك صلاحية ذلك. |
not_found | 404 | لا توجد جلسة أو مستخدم بهذا المعرّف. |
session_closed | 409 | الجلسة نهائية. لا مزيد من الرفع. |
step_not_allowed | 409 | ترتيب خاطئ، أو الخطوة غير مطلوبة الآن. |
revision_conflict | 409 | تغيرت مراجعة الجلسة. اقرأها من جديد. |
idempotency_conflict | 409 | استُخدم Idempotency-Key نفسه مع طلب مختلف. |
challenge_expired | 410 | انتهت صلاحية التحدي أو استُخدم من قبل. اطلب تحديًا جديدًا. |
payload_too_large | 413 | الملف المرفوع كبير جدًا. |
unsupported_media_type | 415 | نوع الملف غير مقبول. |
rate_limited | 429 | طلبات كثيرة جدًا. حاول لاحقًا. |
internal | 500 | حدث خطأ من جهتنا. |
dependency_unavailable | 503 | خدمة نحتاجها متوقفة. حاول لاحقًا. |
رموز الأسباب
تحمل الجلسات reasonCodes عندما تحتاج إلى إعادة إرسال أو عند رفضها. اعرض رسالتك المترجمة لكل رمز. لا تعرض الرمز الخام للمستخدمين أبدًا.
consent_missingconsent_withdrawnattestation_faileddocument_expireddocument_unreadabledocument_not_supporteddocument_suspected_tamperingdocument_number_visiblechip_verification_failedchip_proof_missingchip_data_mismatchmrz_invalidphoto_qualityface_not_foundface_mismatchliveness_failedunderagelocation_not_supportedresidence_not_supportedsanctions_matchpep_reviewduplicate_identitypossible_duplicatedeclaration_requires_reviewuser_requested_reviewreviewer_otheraddress_unreadableaddress_document_too_oldaddress_document_not_acceptedaddress_name_mismatchaddress_signature_requiredfunds_document_unreadablefunds_document_too_oldfunds_document_not_acceptedfunds_more_evidencefunds_evidence_rejected