Zoi ID ile geliştirin
Tek bir adreste iki API, altı dilde tipli istemciler, barındırılan bir akış ve bir sandbox. Kılavuzun tamamı okumaya açık, sandbox anahtarları erken erişimle gelir.
Temel URLhttps://kyc.zoi.network
Hızlı başlangıç
- 1
Oturum oluşturun
Sunucunuz, iş ortağı anahtarınızla
POST /v1/partner/sessionsçağrısı yapar. - 2
Akışı çalıştırın
İstemci jetonunu SDK'ya verin veya
verificationUrladresini bir tarayıcıda açın. - 3
Sonucu alın
Webhook imzasını kontrol edin, ardından kimlik numarasını ve durumunu saklayın.
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
İş ortağı API'si
Sunucudan sunucuya, /v1/partner altında. İş ortağı anahtarınızı Bearer jetonu olarak gönderin. Asla bir uygulamaya koymayın.
İstemci API'si
SDK tarafından, /v1/client altında kullanılır. Bir oturum için 60 dakika geçerli bir istemci jetonu gönderir.
Kurallar
- Zamanlar epoch milisaniyedir ve adı
Atile biten alanlardadır. - Tarihler
YYYY-MM-DDbiçimindedir. Bilinmeyen kısımlarXXolur, örneğin1990-XX-XX. - Bir şey oluşturan veya karar veren POST istekleri
Idempotency-Keybaşlığını kabul eder. Anahtarlar 24 saat tutulur. - Bir oturumdaki değişiklikler bekledikleri sürümü gönderir. Sürüm değiştiyse
revision_conflictalırsınız.
Oturum akışı
Sunucunuz oturumu oluşturur. SDK adımları çalıştırır. Sunucu sırayı kontrol eder ve bir adım erken gelirse step_not_allowed döner.
1. Sunucunuzdan oturum oluşturun
Aynı kullanıcı için tekrar çağırırsanız açık oturum devam eder ve yeni bir istemci jetonu verilir.
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 çalıştırdığı adımlar
- 01
Oturumu ve hâlâ gereken adımları okur.
GET /v1/client/session
- 02
Yüz karşılaştırması için ayrı ve isteğe bağlı seçimle birlikte onayı kaydeder.
POST /v1/client/consent
- 03
Uygulamayı ve cihazı kontrol eder. Sonuç karara dahil edilir.
POST /v1/client/attestation/challenge, POST /v1/client/attestation
- 04
Belgeyi gönderir: MRZ taramasından sonra çipi okur ya da fotoğraf gönderir.
POST /v1/client/document/mrz-scan, POST /v1/client/document/chip/challenge, POST /v1/client/document/chip or POST /v1/client/document/photos
- 05
Uygulama baş hareketlerini gösterirken tek bir kısa ön kamera videosu kaydeder.
POST /v1/client/liveness/challenge, POST /v1/client/liveness
- 06
İkamet ülkesini, gelişmiş seviyede adresi de gönderir.
POST /v1/client/profile
- 07
Yalnızca adres gereksinimi varsa: bir belge yükler, ardından adresi onaylar. Kimlik belgesi adresi zaten verdiyse atlanır.
POST /v1/client/address/document, POST /v1/client/address/confirm
- 08
Yalnızca bir fon gereksinimi varsa: cevapları kaydeder, politika istediğinde belge ekler, ardından adımı tamamlar.
POST /v1/client/funds/answers, POST /v1/client/funds/document, POST /v1/client/funds/remove, POST /v1/client/funds/complete
- 09
İki soruyu cevaplar: siyasi nüfuz sahibi kişi mi ve kendi adına mı hareket ediyor.
POST /v1/client/declarations
- 10
Güncel sürümle gönderir.
POST /v1/client/submit
Kullanıcı ayrıca otomatik bir sonucun bir kişi tarafından incelenmesini isteyebilir (POST /review-request) veya onayını geri çekebilir; bu, oturumu iptal eder ve dosyalarını hemen siler (POST /withdraw).
Adres doğrulama ve fon kaynağı
Kimliğin ötesini doğrulamak için POST /v1/partner/sessions isteğine requirements ekleyin. address adres doğrulaması ister. source_of_funds paranın nereden geldiğini sorar, source_of_wealth ise toplam serveti ve nasıl oluştuğunu da sorar. İki fon değeri birlikte tek bir adımdır ve ikisi de address ile birlikte kullanılabilir.
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" }
}İsteğe bağlı politikalar
Politika göndermezseniz iş ortağı varsayılanınız, o da yoksa bizimki geçerli olur. Politika, oturum oluşturulurken oturuma kopyalanır.
addressPolicy:maxAgeDays(varsayılan 90, 1 ile 366 arası),acceptedTypes(varsayılan: fatura, telekom ve banka belgeleri, vergi belgeleri, kamu kurumu yazıları ve ikametgah belgeleri) vesignedOnly(varsayılan false).fundsPolicy:questions,evidence(none,optionalveyarequired, varsayılannone),acceptedTypes,maxAgeDays(varsayılan 180),currency(ISO 4217, varsayılan USD) ve aralıklar içinbrackets.- Başka gereksinimlerle açılmış ve henüz gönderilmemiş bir oturum, seviye değişikliğinde olduğu gibi iptal edilir ve yenisi başlar.
- Her sonucu
address_signed_pdf,address_document_review,funds_signed_documentsvefunds_reviewgibi sandbox senaryolarıyla test edin.
Takip oturumları
Kimliği sizde zaten aktif olan bir kullanıcı için yalnızca gereksinimleri doğrulayın. requirements ile birlikte reuseIdentity: true gönderin.
- Kullanıcı onay verir ve yalnızca yeni adımları tamamlar. Belge, selfie veya beyanlar yeniden istenmez.
- Onaylandığında kimlik, id'sini, doğrulama tarihini ve geçerliliğini korur ve yeni sonucu alır. Siz
session.approvedveidentity.updatedalırsınız. - Aktif bir kimlik yoksa çağrı 409
step_not_alloweddöner. - Büyük bir para yatırma işlemi, bir PEP işareti veya riskli bir ülke gibi kendi risk kurallarınıza göre başlatın. Kurallarınız sunucunuzda, tek bir yerde kalır.
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", ... } }Sonuçlar ve kapsamlar
Onaylanan oturumlar address ve funds taşır, kimlik de her birinin en güncelini saklar. Özet alanları her kapsamla gelir. Ayrıntılar için kapsam gerekir.
addresskapsamı: adres satırları. Bu kapsam olmadanverified,method,evidenceLevel,documentType,documentDate,verifiedAtvecountryalırsınız.financial_datakapsamı:answers,documentsvefindings. Bu kapsam olmadankinds,evidenceLevel,reviewed,documentCountveverifiedAtalırsınız. Hiçbir zamaneligibilityiçinde yer almaz.evidenceLeveldeğerihigh,medium,lowveyanoneolur. En güçlüden başlayarak adres yöntemleri:wallet,id_document,signed_pdf,official_code,document_reviewvedeclared.- Belgeler API üzerinden gönderilmez. Ortamda
financial_datakapsamı varsa uyum rolüne sahip üyeler fon kaynağı belge sayfalarını panelde görüntüleyebilir. Her görüntüleme kaydedilir.
"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": []
}
}Web akışı
SDK kullanmıyor musunuz? Kullanıcıyı barındırdığımız sayfaya gönderin. Aynı API'yi, aynı kontrolleri ve aynı inceleme kuyruğunu kullanır.
1. Bağlantıyı alın
POST /v1/partner/sessions, verificationUrl döndürür. Kullanıcı bitirdiğinde geri göndermek için redirectUrl verin. Bu adres, kayıtlı yönlendirme kaynaklarınızdan biriyle başlamalıdır.
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",
...
}- İstemci token'ı URL'nin fragment kısmındadır,
#işaretinden sonra. Tarayıcılar fragment'i hiçbir sunucuya göndermez, bu yüzden token loglarda veyaRefererbaşlığında yer almaz. Sayfa onu okur, adres çubuğundan siler ve yalnızca bellekte tutar. - 19 dilden birini seçmek için fragment'e
langekleyin. Eklemezseniz sayfa tarayıcının dilini kullanır. - Sayfa yenilenirse token kaybolur. Aynı oturum için arka ucunuzdan yeni bir bağlantı oluşturun.
- Sayfa, onayla birlikte
channel: "web"gönderir. Tarayıcılar kimlik çiplerini okuyamaz, bu yüzden web oturumları belge fotoğraflarını veya bir dijital kimlik cüzdanını kullanır. Cihaz kontrolünü atlarlar ve webden gelen belge fotoğraflarına her zaman eğitimli bir inceleyici karar verir. - Bilgisayarda sayfa bir QR kodu gösterir, böylece kullanıcı telefonunda devam edebilir.
2. Kullanıcı bitirdiğinde
Akış bittiğinde (gönderildi, iptal edildi veya son bir duruma ulaştı) sayfa bu mesajı şunlardan var olan her birine gönderir: window.ReactNativeWebView, window.webkit.messageHandlers.zoiId, window.ZoiIdAndroid ve window.opener. Sonra zoiIdSession ve zoiIdStatus eklenmiş olarak redirectUrl adresini açar.
Mesaja veya yönlendirme parametrelerine asla güvenmeyin. Yalnızca webhook'unuza veya GET /v1/partner/sessions/:id yanıtına güvenin.
// 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 ayarları
Android WebView
javaScriptEnabled ve domStorageEnabled ayarlarını açın, mediaPlaybackRequiresUserGesture değerini false yapın. Uygulamanız CAMERA iznini aldıktan sonra bir WebChromeClient içinde onPermissionRequest ile RESOURCE_VIDEO_CAPTURE iznini verin. Fotoğraf yedeği için bir dosya seçici ekleyin.
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 veya üstü. allowsInlineMediaPlayback değerini true yapın ve uygulamanıza NSCameraUsageDescription ekleyin. iOS 15 ve üstünde kamera iznine UI delegate içinde karar verebilirsiniz.
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 ve javaScriptEnabled ayarlayın. Uygulamanızın kamera izni olmalıdır.
<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 izinleri ve clickjacking nedeniyle iframe desteklenmez. Bir tarayıcı sekmesi, bir açılır pencere veya bir webview kullanın.
Durumlar
Oturum
created- Oturum var, henüz bir şey yüklenmedi.
in_progress- Onay verildi, adımlar yükleniyor.
processing- Gönderildi, kontroller çalışıyor.
review- Eğitimli bir inceleyiciyi bekliyor.
approved- Son durum. Kimlik doğrulandı.
rejected- Son durum. Gerekçe kodlarına bakın.
resubmit- Kullanıcı requiredSteps içindeki adımları yeniden yapmalı.
expired- Zamanında son karar verilmedi.
cancelled- İş ortağı, kullanıcı veya silme işlemiyle iptal edildi.
Kimlik
active- Kullanılabilir.
suspended- Beklemede, örneğin yeni bir yaptırım adayından sonra.
expired- Belgenin veya doğrulamanın süresi bitti. Yeni bir oturum yeniden doğrular.
revoked- Son durum.
SDK
React Native (Expo) SDK'sı size tipli bir API istemcisi, NFC ile çip okuma ve cihaz kontrolleri verir. Headless çalışır, yani ekranların ve kameranın kontrolü tamamen uygulamanızda kalır. Sunucularınız için TypeScript, Python, Go, PHP, Java ve Ruby tipli istemcilerini kullanın.
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
Bir oturum veya kimlik değiştiğinde webhook göndeririz. İçeriğe güvenmeden önce her zaman imzayı kontrol edin.
- Her webhook bir
Zoi-Id-Signaturebaşlığı taşır:t=unix seconds,v1=hex. v1,t.raw bodymetninin webhook gizli anahtarınızla HMAC-SHA256 değeridir. JSON ayrıştırmadan önceki ham gövdeyi kullanın.- Bir gizli anahtar değiştirilirken başlık her etkin anahtar için bir
v1taşır. Herhangi biri eşleşirse webhook'u kabul edin. tşimdiden 300 saniyeden fazla uzaksa reddedin.- Başarısız gönderimler 72 saat boyunca yeniden denenir. Her deneme yeni bir
tile yeniden imzalanır. - Kimlikler bir
revisiontaşır. Bir olayı yalnızca sürümü sakladığınızdan yeniyse uygulayın.
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"
}
}Olay türleri
session.processingsession.reviewsession.approvedsession.rejectedsession.resubmitsession.expiredsession.cancelledidentity.updatedidentity.suspendedidentity.reinstatedidentity.expiredidentity.revoked
TypeScript'te imzayı kontrol edin
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 imzayı kontrol edin
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
}Olay akışı
GET /v1/partner/events son 30 günün tüm olaylarını en eskiden başlayarak döner. Sonraki sayfayı okumak için son nextCursor değerini after olarak gönderin. Uzun bir kesintiden sonra veya hiçbir şeyi kaçırmadığınızı kontrol etmek için kullanın.
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
}Dolandırıcılık bildirimleri
Karara bağlanmış bir oturumun dolandırıcılık olduğu ortaya çıkarsa, örneğin bir ters ibrazdan sonra, bize bildirin. Bildirimler hatalı onayları ölçmemize katkı sağlar. Oturumu, kimliği veya kullanıcının sonucunu değiştirmez.
- Kapsam
sessions:write. Yalnızca karara bağlanmış oturumlar için (onaylanmış veya reddedilmiş). Karardan önce çağrı 409 döner. - Boş bir gövde,
otherkategorisiyleconfirmed_fraudbildirir.statusayrıcasuspected_fraudolabilir ya da kendi bildiriminizi geri almak içincleared. - Kategoriler:
forged_document,impostor,deepfake_or_replay,synthetic_identity,account_takeoverveother.clearedile kategori gönderilmez. note, analistlerimiz için en fazla 1000 karakterlik serbest bir metindir. İçine asla isim, belge numarası veya başka kişisel veri yazmayın.- Yeni bir bildirim 201 döner. Aynı bildirim tekrar gönderilirse kayıtlı olan 200 ile döner. Güvenle yeniden denemek için
Idempotency-Keygönderin. Oturum başına en fazla 20 bildirim. - Aynı bildirim, panelde oturum sayfasından tek tıkla yapılabilir.
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
}Silme
DELETE /v1/partner/users/:externalUserId, kullanıcı hesabını kapattığında veya silinmesini istediğinde verisini siler. Cevap, şimdi neyin silindiğini ve neyin, neden ve ne zamana kadar tutulduğunu listeler.
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
}Hatalar
Her hata aynı biçimdedir ve her kodun sabit bir HTTP durumu vardır.
{
"error": {
"code": "step_not_allowed",
"message": "This step is not allowed now.",
"requestId": "req_..."
}
}| Kod | HTTP | Anlamı |
|---|---|---|
bad_request | 400 | İstek sözleşmeye uymuyor. |
unauthorized | 401 | Anahtar veya jeton eksik ya da yanlış. |
token_expired | 401 | İstemci jetonunun süresi doldu. Sunucunuzdan yenisini oluşturun. |
forbidden | 403 | Bu anahtar bunu yapamaz. |
not_found | 404 | Böyle bir oturum veya kullanıcı yok. |
session_closed | 409 | Oturum son durumda. Başka yükleme yok. |
step_not_allowed | 409 | Yanlış sıra veya adım şu an gerekli değil. |
revision_conflict | 409 | Oturum sürümü değişti. Yeniden okuyun. |
idempotency_conflict | 409 | Aynı Idempotency-Key farklı bir istekle kullanıldı. |
challenge_expired | 410 | Doğrulama sorusunun süresi doldu veya zaten kullanıldı. Yenisini isteyin. |
payload_too_large | 413 | Yükleme çok büyük. |
unsupported_media_type | 415 | Dosya türü kabul edilmiyor. |
rate_limited | 429 | Çok fazla istek. Daha sonra tekrar deneyin. |
internal | 500 | Bizim tarafımızda bir şeyler ters gitti. |
dependency_unavailable | 503 | İhtiyaç duyduğumuz bir hizmet çalışmıyor. Daha sonra tekrar deneyin. |
Gerekçe kodları
Oturumlar yeniden gönderim gerektiğinde veya reddedildiğinde reasonCodes taşır. Her kod için kendi çevrilmiş mesajınızı gösterin. Ham kodu asla kullanıcıya göstermeyin.
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