Məzmuna keç
Zoi ID

Zoi ID ilə qurun

Bir hostda iki API, altı dildə tipli müştərilər, yerləşdirilmiş axın və sandbox. Tam bələdçi oxumaq üçün açıqdır, sandbox açarları isə erkən girişlə verilir.

Əsas URLhttps://kyc.zoi.network

Sürətli başlanğıc

  1. 1

    Sessiya yaradın

    Backend-iniz tərəfdaş açarı ilə POST /v1/partner/sessions çağırır.

  2. 2

    Axını işə salın

    Müştəri tokenini SDK-ya verin və ya brauzerdə verificationUrl açın.

  3. 3

    Nəticəni alın

    Webhook imzasını yoxlayın, sonra şəxsiyyət ID-sini və statusunu saxlayın.

shell
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" }'

İki API

Tərəfdaş API-si

Serverdən serverə, /v1/partner altında. Tərəfdaş açarınızı Bearer tokeni kimi göndərin. Onu heç vaxt tətbiqə qoymayın.

Müştəri API-si

SDK tərəfindən /v1/client altında istifadə olunur. Bir sessiya üçün 60 dəqiqə etibarlı müştəri tokeni göndərir.

Qaydalar

  • Vaxtlar epoch millisaniyədir, adı At ilə bitən sahələrdə olur.
  • Tarixlər YYYY-MM-DD formatındadır. Bilinməyən hissələr XX olur, məsələn 1990-XX-XX.
  • Nəsə yaradan və ya qərar verən POST sorğuları Idempotency-Key başlığını qəbul edir. Açarlar 24 saat saxlanılır.
  • Sessiyadakı dəyişikliklər gözlənilən versiyanı göndərir. Versiya dəyişibsə, revision_conflict alırsınız.

Sessiya axını

Serveriniz sessiyanı yaradır. SDK addımları icra edir. Server ardıcıllığı yoxlayır və addım erkən gələndə step_not_allowed qaytarır.

1. Serverinizdən sessiya yaradın

Eyni istifadəçi üçün yenidən çağırsanız, açıq sessiya davam edir və yeni müştəri tokeni verilir.

POST /v1/partner/sessions
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-nın icra etdiyi addımlar

  1. 01

    Sessiyanı və hələ lazım olan addımları oxuyur.

    GET /v1/client/session

  2. 02

    Razılığı qeyd edir, üz müqayisəsi üçün ayrıca və könüllü seçimlə birlikdə.

    POST /v1/client/consent

  3. 03

    Tətbiqi və cihazı yoxlayır. Nəticə qərarın bir hissəsidir.

    POST /v1/client/attestation/challenge, POST /v1/client/attestation

  4. 04

    Sənədi göndərir: MRZ skanından sonra çipi oxuyur və ya şəkil göndərir.

    POST /v1/client/document/mrz-scan, POST /v1/client/document/chip/challenge, POST /v1/client/document/chip or POST /v1/client/document/photos

  5. 05

    Tətbiq baş hərəkətlərini göstərərkən ön kamera ilə bir qısa video yazır.

    POST /v1/client/liveness/challenge, POST /v1/client/liveness

  6. 06

    Yaşayış ölkəsini, genişləndirilmiş səviyyədə isə ünvanı da göndərir.

    POST /v1/client/profile

  7. 07

    Yalnız ünvan tələbi ilə: sənəd yükləyir, sonra ünvanı təsdiqləyir. Şəxsiyyət sənədi ünvanı artıq veribsə, bu addım ötürülür.

    POST /v1/client/address/document, POST /v1/client/address/confirm

  8. 08

    Yalnız vəsait tələbi ilə: cavabları saxlayır, siyasət tələb edəndə sənədlər əlavə edir, sonra addımı tamamlayır.

    POST /v1/client/funds/answers, POST /v1/client/funds/document, POST /v1/client/funds/remove, POST /v1/client/funds/complete

  9. 09

    İki suala cavab verir: siyasi xadimdirmi və öz adından hərəkət edirmi.

    POST /v1/client/declarations

  10. 10

    Cari versiya ilə təqdim edir.

    POST /v1/client/submit

İstifadəçi avtomatik nəticənin insan tərəfindən yoxlanmasını da istəyə bilər (POST /review-request) və ya razılığını geri götürə bilər; bu, sessiyanı ləğv edir və fayllarını dərhal silir (POST /withdraw).

Ünvanın təsdiqi və vəsaitlərin mənbəyi

Şəxsiyyətdən artığını yoxlamaq üçün POST /v1/partner/sessions sorğusuna requirements əlavə edin. address ünvanın təsdiqini istəyir. source_of_funds pulun haradan gəldiyini soruşur, source_of_wealth isə ümumi sərvəti və onun necə yarandığını da soruşur. İki vəsait dəyəri birlikdə bir addımdır və hər ikisi address ilə birləşə bilər.

POST /v1/partner/sessions
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" }
}

İstəyə bağlı siyasətlər

Siyasət verilməsə, tərəfdaş standartınız, o da yoxdursa bizimki tətbiq olunur. Siyasət sessiya yaradılanda ona köçürülür.

  • addressPolicy: maxAgeDays (standart 90, 1 ilə 366 arası), acceptedTypes (standart: kommunal, telekom və bank sənədləri, vergi sənədləri, dövlət məktubları və yaşayış arayışları) və signedOnly (standart false).
  • fundsPolicy: questions, evidence (none, optional və ya required, standart none), acceptedTypes, maxAgeDays (standart 180), currency (ISO 4217, standart USD) və aralıqlar üçün brackets.
  • Başqa tələbləri olan və hələ göndərilməmiş açıq sessiya ləğv edilir və səviyyə dəyişikliyində olduğu kimi yenisi başlayır.
  • Hər nəticəni address_signed_pdf, address_document_review, funds_signed_documents və funds_review kimi sandbox ssenariləri ilə test edin.

Əlavə sessiyalar

Şəxsiyyəti sizdə artıq aktiv olan istifadəçi üçün yalnız tələbləri yoxlayın. requirements ilə birlikdə reuseIdentity: true göndərin.

  • İstifadəçi razılıq verir və yalnız yeni addımları tamamlayır. Sənəd, selfi və ya bəyanatlar yenidən istənilmir.
  • Təsdiqdən sonra şəxsiyyət öz ID-sini, yoxlama tarixini və etibarlılıq müddətini saxlayır və yeni nəticəni alır. Siz session.approved və identity.updated alırsınız.
  • Aktiv şəxsiyyət yoxdursa, sorğu 409 step_not_allowed qaytarır.
  • Onu öz risk qaydalarınızla başladın, məsələn böyük depozit, PEP qeydi və ya riskli ölkə olanda. Qaydalarınız backend-inizdə, bir yerdə qalır.
POST /v1/partner/sessions
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", ... } }

Nəticələr və icazələr

Təsdiqlənmiş sessiyalar address və funds daşıyır, şəxsiyyət isə hər birinin ən sonuncusunu saxlayır. Xülasə sahələri istənilən icazə ilə gəlir. Təfərrüatlar üçün icazə lazımdır.

  • address icazəsi: ünvan sətirləri. Onsuz verified, method, evidenceLevel, documentType, documentDate, verifiedAt və country alırsınız.
  • financial_data icazəsi: answers, documents və findings. Onsuz kinds, evidenceLevel, reviewed, documentCount və verifiedAt alırsınız. O heç vaxt eligibility tərkibinə daxil deyil.
  • evidenceLevel dəyəri high, medium, low və ya none olur. Ünvan üsulları, ən güclüdən başlayaraq: wallet, id_document, signed_pdf, official_code, document_review və declared.
  • Sənədlər API vasitəsilə göndərilmir. Mühitdə financial_data icazəsi olanda komplayens rolu olan üzvlər vəsaitlərin mənbəyi sənədlərinin səhifələrinə paneldə baxa bilər. Hər baxış qeydə alınır.
GET /v1/partner/sessions/:id
"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": []
  }
}

Veb axını

SDK yoxdur? İstifadəçini bizim yerləşdirdiyimiz səhifəyə göndərin. O, eyni API-dən, eyni yoxlamalardan və eyni baxış növbəsindən istifadə edir.

1. Linki alın

POST /v1/partner/sessions verificationUrl qaytarır. İstifadəçini sonda geri göndərmək üçün redirectUrl verin. O, qeydiyyatdan keçirdiyiniz yönləndirmə mənbələrindən biri ilə başlamalıdır.

POST /v1/partner/sessions
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",
  ...
}
  • Müştəri tokeni URL-in fragment hissəsindədir, # işarəsindən sonra. Brauzerlər fragmenti heç vaxt serverə göndərmir, ona görə token loglarda və ya Referer başlığında olmur. Səhifə onu oxuyur, ünvan sətrindən silir və yalnız yaddaşda saxlayır.
  • 19 dildən birini seçmək üçün fragmentə lang əlavə edin. Olmasa, səhifə brauzerin dilindən istifadə edir.
  • Səhifəni yeniləmək tokeni itirir. Eyni sessiya üçün backend-inizdən yeni link yaradın.
  • Səhifə razılıqla birlikdə channel: "web" göndərir. Brauzerlər şəxsiyyət çiplərini oxuya bilmir, ona görə veb sessiyalar sənəd şəkillərindən və ya rəqəmsal ID pul kisəsindən istifadə edir. Onlar cihaz yoxlamasını atlayır, vebdən gələn sənəd şəkillərinə isə həmişə təlim keçmiş yoxlayıcı qərar verir.
  • Kompüterdə səhifə QR kod göstərir ki, istifadəçi telefonda davam edə bilsin.

2. İstifadəçi bitirəndə

Axın bitəndə (göndərildi, ləğv edildi və ya son status), səhifə bu mesajı bunlardan mövcud olan hər birinə göndərir: window.ReactNativeWebView, window.webkit.messageHandlers.zoiId, window.ZoiIdAndroid və window.opener. Sonra zoiIdSession və zoiIdStatus əlavə edilmiş redirectUrl ünvanını açır.

Mesaja və ya yönləndirmə parametrlərinə heç vaxt güvənməyin. Yalnız webhook-unuza və ya GET /v1/partner/sessions/:id cavabına güvənin.

postMessage
// 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=processing

3. Webview ayarları

Android WebView

javaScriptEnabled və domStorageEnabled ayarlarını yandırın, mediaPlaybackRequiresUserGesture dəyərini false edin. Tətbiqiniz CAMERA icazəsini aldıqdan sonra WebChromeClient içində onPermissionRequest ilə RESOURCE_VIDEO_CAPTURE icazəsini verin. Şəkil ehtiyat yolu üçün fayl seçici əlavə edin.

Kotlin
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 və ya daha yeni. allowsInlineMediaPlayback dəyərini true edin və tətbiqinizə NSCameraUsageDescription əlavə edin. iOS 15 və daha yenisində kamera icazəsinə UI delegate içində qərar verə bilərsiniz.

Swift
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: NSCameraUsageDescription

React Native WebView

mediaCapturePermissionGrantType="grant", allowsInlineMediaPlayback və javaScriptEnabled təyin edin. Tətbiqinizə kamera icazəsi lazımdır.

TSX
<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.
    }
  }}
/>

Kamera icazələri və clickjacking səbəbindən iframe dəstəklənmir. Brauzer tabı, popup və ya webview istifadə edin.

Statuslar

Sessiya

created
Sessiya var, hələ heç nə yüklənməyib.
in_progress
Razılıq verilib, addımlar yüklənir.
processing
Təqdim edilib, yoxlamalar gedir.
review
Təlim keçmiş yoxlayıcını gözləyir.
approved
Yekun. Şəxsiyyət təsdiqlənib.
rejected
Yekun. Səbəb kodlarına baxın.
resubmit
İstifadəçi requiredSteps içindəki addımları yenidən etməlidir.
expired
Vaxtında yekun qərar verilmədi.
cancelled
Tərəfdaş, istifadəçi və ya silmə ilə ləğv edilib.

Şəxsiyyət

active
İstifadəyə yararlıdır.
suspended
Gözləmədədir, məsələn, yeni sanksiya namizədindən sonra.
expired
Sənədin və ya yoxlamanın müddəti bitib. Yeni sessiya yenidən yoxlayır.
revoked
Yekun.

SDK

React Native (Expo) SDK sizə tipli API müştərisi, NFC ilə çip oxuma və cihaz yoxlamaları verir. Headless işləyir, ona görə ekranlar və kamera tam tətbiqinizin nəzarətində qalır. Serverləriniz üçün TypeScript, Python, Go, PHP, Java və Ruby tipli müştərilərindən istifadə edin.

@zoi/id-sdk
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;
}

Webhook-lar

Sessiya və ya şəxsiyyət dəyişəndə webhook göndəririk. Məzmuna güvənməzdən əvvəl həmişə imzanı yoxlayın.

  • Hər webhook-da Zoi-Id-Signature başlığı olur: t=unix seconds,v1=hex.
  • v1 webhook sirriniz ilə t.raw body mətninin HMAC-SHA256 dəyəridir. JSON təhlilindən əvvəlki xam gövdədən istifadə edin.
  • Sirr dəyişdirilərkən başlıqda hər aktiv sirr üçün bir v1 olur. Hər hansı biri uyğun gələrsə, webhook-u qəbul edin.
  • t indiki vaxtdan 300 saniyədən çox fərqlənirsə, rədd edin.
  • Uğursuz göndərişlər 72 saat ərzində təkrarlanır. Hər təkrar yeni t ilə yenidən imzalanır.
  • Şəxsiyyətlərin revision dəyəri var. Hadisəni yalnız versiyası saxladığınızdan yenidirsə tətbiq edin.
identity.suspended
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"
  }
}

Hadisə növləri

  • session.processing
  • session.review
  • session.approved
  • session.rejected
  • session.resubmit
  • session.expired
  • session.cancelled
  • identity.updated
  • identity.suspended
  • identity.reinstated
  • identity.expired
  • identity.revoked

TypeScript-də imzanı yoxlayın

verify.ts
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-da imzanı yoxlayın

verify.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
}

Hadisə axını

GET /v1/partner/events son 30 günün bütün hadisələrini ən köhnədən başlayaraq qaytarır. Növbəti səhifəni oxumaq üçün son nextCursor dəyərini after kimi göndərin. Uzun fasilədən sonra və ya heç nəyi qaçırmadığınızı yoxlamaq üçün istifadə edin.

GET /v1/partner/events
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
}

Fırıldaq bildirişləri

Qərar verilmiş sessiyanın fırıldaq olduğu üzə çıxanda, məsələn chargeback-dən sonra, bizə bildirin. Bildirişlər səhv təsdiqlərin ölçülməsinə kömək edir. Onlar sessiyanı, şəxsiyyəti və ya istifadəçinin nəticəsini dəyişmir.

  • sessions:write icazəsi. Yalnız qərar verilmiş (təsdiqlənmiş və ya rədd edilmiş) sessiyalar üçün. Qərardan əvvəl sorğu 409 qaytarır.
  • Boş gövdə other kateqoriyası ilə confirmed_fraud bildirir. status həmçinin suspected_fraud və ya öz bildirişinizi geri götürmək üçün cleared ola bilər.
  • Kateqoriyalar: forged_document, impostor, deepfake_or_replay, synthetic_identity, account_takeover və other. cleared ilə kateqoriya verilmir.
  • note analitiklərimiz üçün sərbəst mətndir, ən çoxu 1000 simvol. Ona heç vaxt ad, sənəd nömrəsi və ya digər şəxsi məlumat yazmayın.
  • Yeni bildiriş 201 qaytarır. Eyni bildiriş təkrar göndərilsə, saxlanmış bildiriş 200 ilə qaytarılır. Təhlükəsiz təkrar üçün Idempotency-Key göndərin. Hər sessiyaya ən çoxu 20 bildiriş.
  • Eyni bildiriş paneldəki sessiya səhifəsində bir klik uzaqlıqdadır.
POST /v1/partner/sessions/:id/fraud-reports
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
}

Silmə

DELETE /v1/partner/users/:externalUserId istifadəçi hesabını bağlayanda və ya silinməni istəyəndə onun məlumatını silir. Cavab indi nəyin silindiyini, nəyin saxlandığını, niyə və nə vaxtadək saxlandığını göstərir.

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
}

Xətalar

Hər xətanın forması eynidir və hər kodun sabit HTTP statusu var.

error
{
  "error": {
    "code": "step_not_allowed",
    "message": "This step is not allowed now.",
    "requestId": "req_..."
  }
}
KodHTTPMənası
bad_request400Sorğu müqaviləyə uyğun deyil.
unauthorized401Açar və ya token yoxdur, ya da səhvdir.
token_expired401Müştəri tokeninin müddəti bitib. Serverinizdən yenisini yaradın.
forbidden403Bu açar bunu edə bilməz.
not_found404Belə sessiya və ya istifadəçi yoxdur.
session_closed409Sessiya yekundur. Daha yükləmə olmur.
step_not_allowed409Səhv ardıcıllıq və ya addım hazırda lazım deyil.
revision_conflict409Sessiya versiyası dəyişib. Yenidən oxuyun.
idempotency_conflict409Eyni Idempotency-Key fərqli sorğu ilə istifadə olunub.
challenge_expired410Yoxlama sualının müddəti bitib və ya artıq istifadə olunub. Yenisini istəyin.
payload_too_large413Yükləmə çox böyükdür.
unsupported_media_type415Fayl növü qəbul edilmir.
rate_limited429Çox sorğu. Sonra yenidən cəhd edin.
internal500Bizim tərəfdə nəsə səhv getdi.
dependency_unavailable503Ehtiyac duyduğumuz xidmət işləmir. Sonra yenidən cəhd edin.

Səbəb kodları

Sessiyalar yenidən göndərmə lazım olanda və ya rədd ediləndə reasonCodes daşıyır. Hər kod üçün öz tərcümə olunmuş mesajınızı göstərin. Xam kodu heç vaxt istifadəçiyə göstərməyin.

  • consent_missing
  • consent_withdrawn
  • attestation_failed
  • document_expired
  • document_unreadable
  • document_not_supported
  • document_suspected_tampering
  • document_number_visible
  • chip_verification_failed
  • chip_proof_missing
  • chip_data_mismatch
  • mrz_invalid
  • photo_quality
  • face_not_found
  • face_mismatch
  • liveness_failed
  • underage
  • location_not_supported
  • residence_not_supported
  • sanctions_match
  • pep_review
  • duplicate_identity
  • possible_duplicate
  • declaration_requires_review
  • user_requested_review
  • reviewer_other
  • address_unreadable
  • address_document_too_old
  • address_document_not_accepted
  • address_name_mismatch
  • address_signature_required
  • funds_document_unreadable
  • funds_document_too_old
  • funds_document_not_accepted
  • funds_more_evidence
  • funds_evidence_rejected